Search code examples
cstringiostrtok

Reading from an input file and storing words into an array


The end goal is to output a text file where repeating words are encoded as single digits instead. The current problem I'm having is reading words and storing them into an array.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_CODE 120
void main() {
    FILE *inputfile = fopen("input.txt","rw");
    char buffer[128];
    char *token;
    char *words[MAX_CODE];
    int i = 0;
    while(fgets(buffer, 128, inputfile)){
        token = strtok(buffer," ");
        printf("Token %d was %s",i,token);
        while(token != NULL) {
            words[i] = malloc(strlen(token)+1);
            strcpy(words[i], token);
            i++;
            token = strtok(buffer," ");
        }
    }
for(int i = 0; i<3; i++) printf("%d\n%s\n",i,words[i]);
printf("End");
}

What I get is segmentation fault errors, or nothing. What I want is for words to be an array of strings. I'm allocating memory for each string, so where am I going wrong?


Solution

  • Your second call to strtok should pass NULL for the first argument. Otherwise, strtok will parse the first token over and over again.

        token = strtok(buffer," ");
        printf("Token %d was %s\n",i,token);
        while(i < MAX_CODE && token != NULL) {
            words[i] = malloc(strlen(token)+1);
            strcpy(words[i], token);
            i++;
            token = strtok(NULL," ");
        }
    

    The check against MAX_CODE is for the safety's sake, in case you ever increase the size of your buffer or reduce the value of MAX_CODE. In your current code, the maximum number of space delimited tokens you can hold in a 128 byte buffer is 64.

    From cppreference:

    • If str != NULL, the call is treated as the first call to strtok for this particular string. ...
    • If str == NULL, the call is treated as a subsequent calls to strtok: the function continues from where it left in previous invocation. ...