H.Ozer
H.Ozer

Reputation: 115

C reading text file

I want to read a text file that contains id numbers and names and print those informations line by line. I wrote codes below but output is empty. I cannot find out why it didn't work.

Text file (firms.txt):

101 eti300 superfresh502 pinar91 banvit

Code:

#include <stdio.h>

//prototypes
void readFirms(char *filename);

int main(void) {

    readFirms("C:\\Users\\hakan\\Desktop\\firms.txt");

}

void readFirms(char *filename) {
    FILE *firmFilePtr;

    if ((firmFilePtr = fopen(filename, "r")) == NULL) {
        puts("File could not be opened.");
    } else {
        unsigned int firmId;
        char *firmName;

        fscanf(firmFilePtr, "%d%s", &firmId, firmName);

        while (!feof(firmFilePtr)) {
            printf("%d %s\n", firmId, *firmName);
            fscanf(firmFilePtr, "%d %s", &firmId, firmName);
        }
        fclose(firmFilePtr);
    }
}

Upvotes: 2

Views: 93

Answers (2)

chqrlie
chqrlie

Reputation: 144740

Your code has multiple problems:

  • the loop test is incorrect: Why is “while ( !feof (file) )” always wrong? You should instead call fscanf() in the while test expression and compare the return value with 2.

  • the file contents does not match the format you are trying to parse: the first 101 will match %d, then eti300 matches %s, but the next call to fscanf() fails because superfresh502 does not match %d and any subsequent calls fail because the offending input is still pending in the input stream.

  • firmName is an uninitialized pointer, passing it as the destination to fscanf for the %s conversion specifier has undefined behavior.

Here is a modified version:

#include <stdio.h>

//prototypes
void readFirms(char *filename);

int main(void) {
    readFirms("C:\\Users\\hakan\\Desktop\\firms.txt");
    return 0;
}

void readFirms(char *filename) {
    FILE *firmFilePtr;

    if ((firmFilePtr = fopen(filename, "r")) == NULL) {
        puts("File could not be opened.");
    } else {
        unsigned int firmId;
        char firmName[100];

        while (fscanf(firmFilePtr, "%d%99s", &firmId, firmName) == 2) {
            printf("%d %s\n", firmId, firmName);
        }
        fclose(firmFilePtr);
    }
}

Upvotes: 2

fscanf("%s", ...) reads a string: all characters valid for a string are read into it, until whitespace is encountered (or the file ends). Note that eti300 is a perfectly valid string, and as such, all of it is consumed by the first fscanf. This leaves no number for the second fscanf to start with, so it errors.

If you can, change the format of your data to introduce whitespace (such as a newline) between a name and the next ID number following it.

If that is not an option, you will have to parse the numbers out of the strings manually (such as finding the first digit and splitting the string there). This could be done via character-by-character reads from the file, or by reading the data into memory as strings and processing it there.

Upvotes: 0

Related Questions