Getting words from text file to an array

前端 未结 3 1794
既然无缘
既然无缘 2021-01-14 12:43

My text file is formated like that:

my.txt
Red
Green
Blue
Yellow

I\'m tring to get words like that:

typedef char * string;
         


        
相关标签:
3条回答
  • 2021-01-14 13:03

    You'll need to allocate memory for your null-terminated strings.

    At the moment you are only allocating memory for 4 char *, but these pointers are uninitialized and therefor will result in UB (undefined behavior) when you try to write data to the memory pointed to by them.


    Working example snippet

    The use of "%127s" in the below snippet is to prevent us writing outside the bounds of the allocated memory. With the format-string in question we will at the most read/write 127 bytes + the null-terminator.

    Please remember that further error checks should be implemented if this is to be used in "real life".

    • Check to see that file_handle is indeed valid after attempt to open the file
    • Check to see that malloc did indeed allocate requested memory
    • Check to see that fscanf read the desired input

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int
    main (int argc, char *argv[])
    {
      int i;
      char * lines[4];
      FILE *file_handle = fopen ("my.txt", "r");
    
      for (i =0; i < 4; ++i) {
        lines[i] = malloc (128); /* allocate a memory slot of 128 chars */
        fscanf (file_handle, "%127s", lines[i]);
      }
    
      for (i =0; i < 4; ++i)
        printf ("%d: %s\n", i, lines[i]);
    
      for (i =0; i < 4; ++i)
        free (lines[i]); /* remember to deallocated the memory allocated */
    
      return 0;
    }
    

    output

    0: Red
    1: Green
    2: Blue
    3: Yellow
    
    0 讨论(0)
  • 2021-01-14 13:07

    Since all the other answers told you what you did wrong but not how to fix it. Here

    typedef char * string;
    #define LEN 100 //long enough for your line
    main(){
       int i;
       string array[4];
    
       for(i = 0; i < 4; i++) {
          if((array[i] = (char *)(malloc(sizeof(char) * LEN))) == NULL) {
              printf("malloc failed");
              return 1;
          }
       } 
    
       FILE *my;
       my = fopen("my.txt","r");
       for(i = 0; i < 4; i++)
             fscanf(data, "%s", &array[i]);
       fclose(my);
    }
    

    And like they said you made space for the pointers but not for what the pointers point to.

    0 讨论(0)
  • 2021-01-14 13:13

    You try to read some data, but you don't have anywhere to put it. All you have is 4 pointers, pointing to god knows where and you are trying to write into it!

    There are many ways to do this:

    1. You know the bound to the size of the data:

      #include <stdio.h>
      
      #define MAX_CHARS 20
      
      typedef char string[MAX_CHARS+1];  // leave one space for '\0'
      
      main(){
         int i;
         string array[4];
      
         FILE *my;
         my = fopen("my.txt","r");
         for(i = 0; i < 4; i++)
               fscanf(data, "%s", array[i]);  // no need for & with %s
         fclose(my);
      }
      
    2. Assume a bound to the size of the data, and ignore the rest of the strings (if it was too big):

      #include <stdio.h>
      
      #define MAX_CHARS 20
      #define MAX_CHARS_STR "20"  // there are better ways to get this
      
      typedef char string[MAX_CHARS+1];
      
      main(){
         int i;
         string array[4];
      
         FILE *my;
         my = fopen("my.txt","r");
         for(i = 0; i < 4; i++){
               fscanf(data, "%"MAX_CHARS_STR"s", &array[i]);  // read at most 20 chars for the string
               ungetc('x', data);     // append one character to make sure we don't hit space
               fscanf(data, "%*s");   // ignore whatever is left of string
         }
         fclose(my);
      }
      
    3. Read the file twice, first time find out the sizes of each string (or the maximum size, for simplicity), then allocate memory for the strings (using malloc). Then read the file again and this time actually store the strings:

      #include <stdio.h>
      
      typedef char *string;
      
      main(){
         int i;
         string array[4];
         int cur_size = 0;
      
         FILE *my;
         my = fopen("my.txt","r");
         for(i = 0; i < 4; i++){
               fscanf(data, "%*s%n", &cur_size);
               array[i] = malloc((cur_size+1)*sizeof(*array[i]));
         }
         fclose(my);
      
         my = fopen("my.txt","r");
         for(i = 0; i < 4; i++){
               fscanf(data, "%s", array[i]);
         }
         fclose(my);
      
         // and when done:
         for(i = 0; i < 4; i++){
               free(array[i]);
         }
      }
      
    4. Read from the input chunk by chunk. For each string, if input string was not finished yet resize the memory allocated for the string (increase its size), read another chunk and check again. Method 3 is faster though and I recommend it, but just so you know, this is basically what happens in C++'s string.

    0 讨论(0)
提交回复
热议问题