I have done a code (below) to read the numbers from a .txt file. The first two numbers are to be put on a int variable, the numbers from the second line onwards are to be put on an array of strings. But I have a problem, if there is a blank/empty line at the end of the file some symbols are added on the array.
Example of the file with error:
10 20
45000000
48000000
56000000
-empty/blank line-
Code:
#include <stdio.h>
#include <conio.h>
#define MAX 100
int main(void) {
FILE *file;
int primNum;
int secNum;
int counter = 0;
//Count number of lines
int numberOfLines = 0;
char ch;
file = fopen("file.txt", "rt");
if (file == NULL) {
printf("Error\n");
return 1;
}
for (ch = getc(file); ch != EOF; ch = getc(file)) {
if (ch == '\n')
numberOfLines++;
}
numberOfLines++;
fclose(file);
rewind(file);
printf("Total number of lines are: %d\n", numberOfLines);
//Continue
file = fopen("file.txt", "rt");
char listOfNumbers[numberOfLines][MAX];
if (file == NULL) {
printf("Error\n");
return 1;
}
int i = 0;
while (counter < numberOfLines) {
if (counter == 0) {
fscanf(file, "%d %d\n", &primNum, &secNum);
} else {
fscanf(file, "%s\n", listOfNumbers[i]);
i++;
}
counter++;
}
//Testing Results
printf("\n1st Number: %d", primNum);
printf("\n2nd Number: %d", secNum);
printf("\n\nList of Numbers on Array:");
for (i = 0; i < numberOfLines - 1; i++) {
printf("\n%s", listOfNumbers[i]);
}
fclose(file);
return 0;
}
It returns:
Total number of lines are: 5
1st Number: 10
2nd Number: 20
List of Numbers on Array:
45000000
48000000
56000000
←┤¼v'0@
The line counter correctly says it’s 5 lines (counting the empty/blank one), but I need it to ignore it and still be able to put all of the numbers from the second line onwards on the array. I’m stuck with this problem and don’t know how to solve it.
>Solution :
You use fscanf() to read the contents of the file, fscanf() ignores white space and newlines. You should use the same calls to count the number of items and to actually read them after rewinding the stream pointer. Note that you call to rewind(file) after you close the file has undefined behavior.
Also note that ch must be defined as int to handle EOF reliably.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
int main() {
FILE *file = fopen("file.txt", "r");
if (file == NULL) {
fprintf(stderr, "Cannot open file.txt: %s\n", strerror(errno));
return 1;
}
// read the 2 numbers
int primNum, secNum;
if (fscanf(file, "%d %d\n", &primNum, &secNum) != 2) {
fprintf(stderr, "invalid file format\n");
fclose(file);
return 1;
}
// count the number of items that can be read
char line[100];
int counter;
for (counter = 0; fscanf(file, "%99s", line) == 1; counter++)
continue;
printf("Total number of items: %d\n", counter);
// Rewind and re-read the contents into the array
rewind(file);
char listOfNumbers[count][100];
int i;
if (fscanf(file, "%d %d\n", &primNum, &secNum) != 2) {
fprintf(stderr, "cannot reread the numbers\n");
fclose(file);
return 1;
}
for (i = 0; i < counter; i++) {
if (fscanf(file, "%99s", listOfNumbers[i]) != 1) {
// Cannot read all the numbers file changed ?
printf("could only read %d numbers out of %d\n", i, counter);
counter = i;
break;
}
}
// Testing Results
printf("1st Number: %d\n", primNum);
printf("2nd Number: %d\n\n", secNum);
printf("List of Numbers on Array:\n");
for (i = 0; i < counter; i++) {
printf("%s\n", listOfNumbers[i]);
}
fclose(file);
return 0;
}