3

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

}`

2
  • 1
    It always amazes me how much can go wrong when you throw C, strings and an unexperienced programmers in a room... Commented Nov 10, 2013 at 10:34
  • I've just slightly edited your post to fix some formatting in the body and in the title of the question (e.g. "C" written in upper-case). Commented Nov 10, 2013 at 10:56

3 Answers 3

1

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

hashTable = createTable();
hashTable = createWordTable();
Sign up to request clarification or add additional context in comments.

Comments

1

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, e.g.:

+---+---+---+---+---+-----+---+---+---+---+---+-----+-----+
| 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, i.e. 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;
}

2 Comments

I am not sure if it is an option. You lose the possibility to have empty strings...
@glglgl: You're right about the empty strings. If empty strings are required, then another option can be to use a kind of "header" before the structure described above, storing a sequence of string pointers, and terminating it with a NULL pointer. After that header (containing the string pointers), the strings follow.
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.

1 Comment

i did this earlier but i experienced exc_bad_access problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.