Reputation: 115
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
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
Reputation: 171127
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