1

I have a file with different words separated by newlines. How can i read and store each word in an array of strings? 1 word, 1 row of the array. I'm posting this code, but im pretty sure it doesnt work, because i can't understand if i should use fgets or fscanf and how i can write each word in each line of my array.

int file_string_temp_number_rows=200;
int file_string_temp_number_cols=200;
char **file_string_arr = (char**)malloc (file_string_temp_number_rows*sizeof(char));

for ( i = 0 ; i < file_string_temp_number_rows ; i++){
    file_string_arr[i] = (char*)malloc(file_string_temp_number_cols*sizeof(char));
}


if ((file_ptr= fopen(filename, "r"))){

    if((file_ptr=fopen(filename,"r"))==NULL)
    {
       printf("errore apertura file");
       return 1;  
    }
    else{
        while(!feof(file_ptr)){
            for(i = 0 ; i < file_string_temp_number_rows ; i++){
                    for(j = 0 ; j < file_string_temp_number ; j++){
                        fgets(file_string_arr , 40 , filename);
                        }
                    }
                }   
            }
        }
    }
4
  • See: Why is “while ( !feof (file) )” always wrong? Commented Dec 5, 2018 at 16:29
  • 1
    Your first malloc should be *sizeof(char *) as you want to allocate room for pointers. Commented Dec 5, 2018 at 16:29
  • 5
    Also, why are you opening the file twice ? Commented Dec 5, 2018 at 16:30
  • 2
    I rolled your post back to its original content. In general, It is not a good idea to edit your post to make corrections using content from either comments or answers. (other than formatting, or additional information that clarifies your question(s)) It causes people to have to chase the solution. That is, when you edit other peoples suggestions into your answer, the problem becomes a moving target. Commented Dec 5, 2018 at 17:53

1 Answer 1

2

Addressing your title question: How do i read an array of strings from a file?

There are many approaches to do this. Here is a list of basic steps that could be used.

1) Using fopen(), open file and scan to determine the following:
- Maximum word length.
- Count of words in file.

2) Create container: - Use calloc() to create an array of strings for words.

3) Using fopen() (again), fgets() and strtok() (or variant) to parse content of file into string array.

Note, The sample implementation snippets below use particular functions and techniques, but you should not limit your implementation to only these. There are many paths that would work just as well, so do not be afraid to experiment. For example, either fgets() or fscanf() could be used to solve this problem. The methods highlighted below are just examples of one way to do the task.

Scan example

// provides count of words, and longest word

int longestWord(char *file, int *nWords)
{
    FILE *fp=0;
    int cnt=0, longest=0, numWords=0;
    char c;
    fp = fopen(file, "r");
    if(fp)
    {

     // if((strlen(buf) > 0) && (buf[0] != '\t') && (buf[0] != '\n') && (buf[0] != '\0')&& (buf[0] > 0))

        while ( (c = fgetc(fp) ) != EOF )
        {
            if ( isalnum (c) ) cnt++;
            else if ( ( ispunct (c) ) || ( isspace(c) ) || (c == '\0' ))
            {
                (cnt > longest) ? (longest = cnt, cnt=0) : (cnt=0);
                numWords++;
            }
        }
        *nWords = numWords;
        fclose(fp);
    }
    else return -1;

    return longest;
}

//in main eg:
int longest;
int count;
...
longest = longestWord(".\\file.txt", &count);//longest and count will be 
                                             //used to create string arrays

Create string array example

//Create string arrays to contain words using result from original scan of file
char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen)
{
    int i;
    char **a = {0};
    a = calloc(numStrings, sizeof(char *));
    for(i=0;i<numStrings; i++)
    {
      a[i] = calloc(maxStrLen + 1, 1);
    }
    return a;
}
// in main(): Create array of words
char **words = Create2DStr(count, longest);//Using values obtained from scan section above
if(words) { //continue

Parse into word strings example

// in main(), after performing scan and array creation:
const char delim[] = {" \n\t"};
char line[260];
char *buf = NULL;

fp = fopen(".\\file.txt", "r");
cnt=0;
while(fgets(line, 260, fp))//keep reading lines until EOF
{
    buf = strtok(line, delim);
    while(buf)//continue until last word in line is parsed
    {    
        if((strlen(buf) > 0) 
        {
            strcpy(words[cnt], buf);
            cnt++; //use as accurate count of words.
        }
        buf = strtok(NULL, DELIM);
    }
}
fclose(fp);
Sign up to request clarification or add additional context in comments.

5 Comments

Hi, i appreciated your answer. Can i ask you what last two while cycles do? When does while(buf) stops and why?
@GiacomoMasciarelli - Both loops exit when seeing a NULL. Specifically, fgets() returns a NULL when there is nothing else to read, ( i.e. EOF), so the outer loop will continue until it sees a NULL. The inner loop, similarly, also continues until it sees a NULL, but in this case it is looking at the return value of the strtok() function. I included links to both of these functions (fgets() and strtok()) in the post above. Be sure to take a look at both of them, in particular read about their return types.
mb i didn't know that NULL automatically ends while cycles, thanks
@GiacomoMasciarelli - You are welcome. Yes, the while(condition){...} construct continues to loop as long as condition is TRUE. As soon as condition becomes FALSE, it exits the construct. NULL by definition evaluates to FALSE. BTW, Thank you for accepting!
char c; should be int c;, otherwise EOF detection may not work.

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.