【问题标题】:Returning array of strings from function in C从C中的函数返回字符串数组
【发布时间】:2013-11-22 04:56:16
【问题描述】:

我从给定文件(字典)中读取单词到单个字符串,并将字符串分配给字符串数组的第 n 个索引。但它不起作用。 main() 中 for 循环的输出始终是 e3V\347 等,createWordTable() 中 for 循环的输出始终是字典的最后一个单词。这是我的代码

char** createWordTable();

char** createTable();

int main()
{

    int i;
    char **hashTable;
    hashTable = createTable();
    hashTable = createWordTable();



    for (i=0; i< 338; i++) {
        printf("%s \n",hashTable[i]);
    }

    return 0;
}

char** createWordTable(){

    char  word[20],**table;
    FILE *dicFile;
    table = createTable();

    dicFile = fopen("smallDictionary.txt", "r");
    if (dicFile == NULL) {
        perror("error");
    }
    int wordCount = 0,endFile = 1;
    while (endFile != EOF) {
        endFile = fscanf(dicFile,"%s",word);
        table[wordCount] = word;
        wordCount = wordCount+1;
    }
    for (int i=0; i< 338; i++) {
        printf("%s \n",table[i]);
    }
    return table;

}

char** createTable(){

    char **table;
    int i;
    table = (char **)malloc(338 * sizeof(char *));
    for (i=0; i<=338; i++) {
        *table = (char *)malloc(25 * sizeof(char));
    }
    return table;
}

我将代码更改为此及其工作!我定义了全局变量“表”并删除了指针(也是动态分配函数)。我很好奇为什么指针不适用于此代码的 C 中的字符串数组(我知道方括号也表示“指针”)?因为我对整数数组没有不好的经验。抱歉英语不好,这是新代码:`

字符词[338][10];

int main()

{

createWordTable();

for (int i=0; i< 338; i++) {
    printf("%s \n",words[i]);
}


return 0;

}

void createWordTable(){

char  word[20];

FILE *dicFile;


dicFile = fopen("smallDictionary.txt", "r");
if (dicFile == NULL) {
    perror("error");
}
int wordCount = 0;
while (!feof(dicFile)) {
    fscanf(dicFile,"%s",word);
    if(feof(dicFile)) break; 
   strcpy(words[wordCount], word);

    wordCount = wordCount+1;
}

 fclose(dicFile);

}`

【问题讨论】:

  • 当你把 C、字符串和一个没有经验的程序员扔在一个房间里时,我总是很惊讶会出错多少......
  • 我刚刚稍微编辑了您的帖子,以修正正文和问题标题中的一些格式(例如,"C" 以大写形式书写)。

标签: c arrays string


【解决方案1】:

您正在丢失您的 createTable() 结果。将其存储在单独的指针变量中。

hashTable = createTable();
hashTable = createWordTable();

【讨论】:

    【解决方案2】:

    从函数返回字符串数组的一个选项是使用double-NUL-terminated strings

    这个数据结构是一个字符串序列,一个接一个地存储在内存中,每个NUL-终止,并在末尾有一个附加NUL-终止符,例如:

    +---+---+---+---+---+-----+---+---+---+---+---+-----+-----+
    | H | e | l | l | o | NUL | w | o | r | l | d | NUL | NUL |
    +---+---+---+---+---+-----+---+---+---+---+---+-----+-----+
                                                     ^^^^^^
                                          Double-NUL at the end
    

    您可以从函数返回指向第一个字符串的指针,即指向序列的开头。

    这种数据结构的一大优点是它对数组中的字符串有很好的局部性

    这种数据结构实现起来并不难,而且易于导航,从下面的源码可以看出:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define ARRAY_SIZE(a)   (sizeof(a) / sizeof(a[0]))
    
    char * build_string_array(void) {
        const char * test_strings[] = {
            "Hello",
            "World",
            "Hi",
            "John",
            "Connie"
        };
        int i;
        char * p;
        char * string_array;
        int total_len;
    
        /* Calculate total length of strings */
        total_len = 0;
        for (i = 0; i < ARRAY_SIZE(test_strings); i++) {
            /* Update total length with current string. +1 for '\0' */
            total_len += strlen(test_strings[i]) + 1;
        }
    
        /* Consider double-NUL termination */
        total_len++;
    
        /* Allocate memory for the resulting string array */
        string_array = malloc(total_len);
        if (string_array == NULL)
            return NULL; /* error */
    
        /* Copy source strings to the destination string array memory */
        p = string_array;
        for (i = 0; i < ARRAY_SIZE(test_strings); i++) {
            strcpy(p, test_strings[i]);
            p += (strlen(p) + 1); /* +1 to skip terminating NUL */
        }
    
        /* Terminate with double-NUL */
        *p = '\0';
    
        /* Return the address of the string array to the caller */
        return string_array;
    }
    
    int main() {
        char * test_string_array;
        const char * p;
    
        /* Create the test string array */
        test_string_array = build_string_array();
        if (test_string_array == NULL) {
            printf("Error in creating array.\n");
            return 1;
        }
    
        /* Print string array content */
        for (p = test_string_array; *p != '\0'; p += (strlen(p) + 1)) {
            printf("%s\n", p);
        }
    
        /* Free array memory */
        free(test_string_array);
    
        /* All right */
        return 0;
    }
    

    【讨论】:

    • 我不确定这是否是一个选项。你失去了有空字符串的可能性......
    • @glglgl:关于空字符串,你是对的。如果需要空字符串,则另一种选择是在上述结构之前使用一种“标题”,存储一系列字符串 pointers,并以NULL 指针终止它。在该标头(包含字符串指针)之后,是字符串。
    【解决方案3】:

    您应该将fscanf 直接从word 转换为table[wordcount]strcpy。否则每个条目将只指向包含文件中最后一个字符串的单词。

    【讨论】:

    • 我之前做过这个,但我遇到了 exc_bad_access 问题。
    猜你喜欢
    • 2013-03-25
    • 2013-10-01
    • 2014-11-06
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多