Thread: Reading strings from a text file and storing into an array help!

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    4

    Reading strings from a text file and storing into an array help!

    Hey all,

    I've been making a program that reads in from a .txt file which is a dictionary of one word on each line like so;

    aa
    aah
    aahed
    aahing
    aahs
    aal
    aalii
    aaliis
    aals

    What I want to do is read in from the text file and store each string from each line into an array and be able to call that string later on. For example with the above text calling words[1] would return "aah". Here is my code that I have so far below, at first it seems to work but it looks like it fills all of the array with the last word in the text file? Any help would be greatly appreciated!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main ()
    {
    
    
    int dicsize = 80368;
    char newword[100];
    char* words[dicsize-1];
    
    
    // Load Files
    FILE *dict;
    dict=fopen("dictionary.txt", "r");
    if (dict==NULL) {
    printf("Unable to open dictionary.txt\n");
    } else {
    // Input Dictionary
     int i = 0;
     while (fgets(newword, sizeof newword, dict) != NULL) {
     printf("%s", newword);
     words[i] = newword;
     i++;
     }
    }
    
    
    
    
    printf("\nTest: %s", words[2]);
    
    
    
    
    
    
    return(0);
    }

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Yes, because 'words' is an array of pointers, and you pointed all of them to the same place, newword. After the loop ends, newword contains the last value that was placed into it.

    You need something like:

    Code:
    char words[dicsize-1][100];
    Then you need to

    A) copy the string in newword into a place in newwords at each iteration.
    or
    B) just use words[i] in fgets and forget about newwords.

    By "copy", I mean strcpy() or something similar. You cannot assign the content of an entire array (a string is an array of characters) with =.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Why declare words to have dicsize-1 entries? Are you intentionally leaving one word out? You should also have a check in your while loop that ensures you don't enter too many words, that would create a buffer overrun.

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    Quote Originally Posted by MK27 View Post
    Yes, because 'words' is an array of pointers, and you pointed all of them to the same place, newword. After the loop ends, newword contains the last value that was placed into it.

    You need something like:

    Code:
    char words[dicsize-1][100];
    Then you need to

    A) copy the string in newword into a place in newwords at each iteration.
    or
    B) just use words[i] in fgets and forget about newwords.

    By "copy", I mean strcpy() or something similar. You cannot assign the content of an entire array (a string is an array of characters) with =.
    Ah I understand now that at the end of the loop all of the pointers are pointing to one value(newword), this means I need to store newword into an array?

    Could you explain a little bit more about how to implement the 2d array?

    Thanks for your help

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    What don't you get? I think MK27 was quite clear. He gave you the declaration verbatim. Suggestion "B", to use words[i] as the buffer you read into with fgets also seems straight forward. Why not give it your best effort and post back if you still have trouble.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    The code im trying below gives me the error Segmentation fault (core dumped);

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main ()
    {
    
    
    int dicsize = 80368;
    int newword = 100;
    char words[dicsize-1][100];
    
    
    // Load Files
    FILE *dict;
    dict=fopen("dictionary.txt", "r");
    if (dict==NULL) {
    printf("Unable to open dictionary.txt\n");
    } else {
    // Input Dictionary
     int i = 0;
     while (fgets(words[i], sizeof newword, dict) != NULL) {
     i++;
     }
    }
    
    
    return(0);
    }
    Any suggestions?

    Thanks

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    char words[dicsize-1][100];
    This is rather big ( > 8 MB ) for the stack. You should dynamically allocate the array.
    Code:
    while (fgets(words[i], sizeof newword, dict) != NULL) {
    guess you want newword instead of sizeof newword.
    Kurt

  8. #8
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    You should never use VLA, VLA are bad, only C99, without error-handling and not C++ compatible.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXWORDNUM 90000
    #define MAXWORDLEN 100
    
    int main ()
    {
    char words[MAXWORDNUM][MAXWORDLEN];
    
    FILE *dict;
    dict=fopen("dictionary.txt", "r");
    if (dict==NULL) {
    printf("Unable to open dictionary.txt\n");
    } else {
     int i = 0;
     while (i<MAXWORDNUM && fgets(words[i], MAXWORDLEN, dict) != NULL) {
      if( words[i][strlen(words[i])-1]=='\n' ) 
       words[i][strlen(words[i])-1]='\0'; /* remove a newline here */
     i++;
     }
    }
    
    
    return(0);
    }

  9. #9
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by BillyTKid View Post
    You should never use VLA, VLA are bad, only C99, without error-handling and not C++ compatible.
    I don't see what's so bad about variable length arrays. And they certainly are C++ compatible.
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  10. #10
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    Right I have decided to go a different way and use structures for each word, the following code gives me the same Segmentation fault error, could anyone explain why this is happening?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define maxwords 90000
    #define maxwordlen 100
    
    
    typedef struct words
    {
    char word[maxwordlen];
    } words;
    
    
    int main ()
    {
    words wordlist[maxwords];
    char tempword[maxwordlen];
    
    
    FILE *dict;
    dict=fopen("dictionary.txt", "r");
    if (dict==NULL) {
    printf("Unable to open dictionary.txt\n");
    } else {
     int i = 0;
     while (i<maxwords && fgets(tempword, maxwordlen, dict) != NULL) {
     fgets(wordlist[i].word, maxwordlen, dict);
     i++;
     }
    }
    
    
    fclose(dict);
    
    
    return(0);
    }
    Thanks for your time

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Code:
     while (i<maxwords && fgets(tempword, maxwordlen, dict) != NULL) {
     fgets(wordlist[i].word, maxwordlen, dict);
     i++;
     }
    This code reads two words at a time from the file and stores each word in different locations. I don't think it should cause a segfault, but you probably want to fix that nonetheless.

  12. #12
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    Quote Originally Posted by QuantumPete View Post
    I don't see what's so bad about variable length arrays.
    Can you read?
    Quote Originally Posted by QuantumPete View Post
    And they certainly are C++ compatible.
    VLA are not supported by C++98,C++03,C++11, therefore VLA are not compatible with C++.

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Why does C++ compatibility matter here?

  14. #14
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by BillyTKid View Post
    Can you read?
    I most certainly can. Otherwise, how would I have read your post???
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading from File and Storing into Array
    By Magic staple in forum C Programming
    Replies: 13
    Last Post: 12-05-2011, 12:00 AM
  2. Reading an array of strings from a text file?
    By jeanermand in forum C Programming
    Replies: 9
    Last Post: 11-14-2011, 09:41 PM
  3. Replies: 7
    Last Post: 04-01-2011, 07:57 PM
  4. Help - Reading a file and storing it as a 2d Array.
    By MetallicaX in forum C Programming
    Replies: 2
    Last Post: 03-08-2009, 07:33 PM
  5. Reading strings from a file and storing into an array
    By Rizage in forum C++ Programming
    Replies: 1
    Last Post: 10-24-2002, 03:04 AM