简体   繁体   中英

Returning array of strings from function in C

I read words from given file (dictionary) to single string and I assign the string to nth index of string array. But it does not work. Output of the for loop in the main() is always e3V\\347 etc. and output of the for loop in the createWordTable() is always last word of dictionary. Here is my code

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;
}

I changed code to this and its work! I defined global variable 'table' and removed pointers (also dynamic allocation functions). I'm very curious why pointers don't work with array of strings in C for this code (I know square brackets also mean 'pointer') ? Because i have no bad experience with integer arrays. Sorry for bad English, here is new code :`

char words[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);

}`

You are losing your createTable() result. Store it separate pointer variables.

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

An option to return an array of strings from a function is to use double- NUL -terminated strings .

This data structure is a sequence of strings, one stored in memory after the other, each NUL -terminated, and with an additional NUL -terminator at the end, eg:

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

You can return from the function the pointer to the first string, ie to the beginning of the sequence.

One of the great advantages of this data structure is that it has very good locality for strings in the array.

This data structure is not hard to implement, and it's easy to navigate , as you can see from the following source code:

#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;
}

You should fscanf directly into table[wordcount] or strcpy from word . Otherwise every entry will just point to word, which contains the last string in the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM