Reputation: 108
I am trying to make a program that reads numbers from a text file named numbers.txt that contains different numbers in each line.
For example:
8321
12
423
0
...
I have created this program, but it does not work properly. I have tried many things and don't know what to do. Can someone guide me in the right direction? Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
int main(int argc, char *argv[]) {
char str[MAX_LEN];
FILE *pFile = fopen(argv[1], "r");
int num;
int sum = 0;
int count = 0;
if (pFile == NULL) {
printf("Error opening file.\n");
return 1;
}
while (!feof(pFile) && !ferror(pFile)) {
if (fscanf(pFile, "%d", &num) == 1) {
count++;
while (strcmp(fgets(str, MAX_LEN, pFile), "\0") == 0) {
printf("%s", str);
//sum = sum + (int)(fgets(str, MAX_LEN, pFile));
printf("\n");
}
}
}
fclose(pFile);
printf("count = %d \n", count);
printf("sum = %d \n", sum);
return 0;
}
Upvotes: 1
Views: 2867
Reputation: 144780
Your program has multiple problems:
while (!feof(pFile) && !ferror(pFile))
is always wrong to iterate through the file: feof()
gives valid information only after a actual read attempt. Just test if the read failed.fscanf(pFile, "%d", &num) == 1)
add the number instead of just counting the numbers.strcmp(fgets(str, MAX_LEN, pFile), "\0")
will fail at the end of the file, when fgets()
returns NULL
.If the file only contains numbers, just read these numbers with fscanf()
and add them as you progress through the file.
Here is a modified version:
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *pFile;
int num
int sum = 0;
int count = 0;
if (argc < 2) {
printf("Missing filename\n");
return 1;
}
if ((pFile = fopen(argv[1], "r")) == NULL) {
printf("Error opening file %s\n", argv[1]);
return 1;
}
while (fscanf(pFile, "%d", &num) == 1) {
sum += num;
count++;
}
fclose(pFile);
printf("count = %d \n", count);
printf("sum = %d \n", sum);
return 0;
}
Upvotes: 0
Reputation: 3699
You can use strtok
to split the numbers in each line, then using atoi
function to convert string to int
.
For example:
while(fgets(str, MAX_LEN, pFile)) {
// if the numbers are separated by space character
char *token = strtok(str, " ");
while(token != NULL) {
sum += atoi(token);
strtok(NULL, " ");
}
}
if there is only one number per line, you do not need to use strtok
:
while(fgets(str, MAX_LEN, pFile)) {
sum += atoi(str);
// OR
sscanf(str,"%d\n", &new_number)
sum += new_number;
}
Upvotes: 0
Reputation: 42139
strcmp(fgets(str, MAX_LEN, pFile),"\0")
is wrong in many ways. For one, the argument of strcmp
must be a string (which a null pointer isn't), but fgets
returns NULL
on error or end of file. You need to check that it didn't return NULL
and then you can compare the string in str
. However, there is no need to strcmp
against "\0"
(or, in this case equivalently, ""
) to detect the end of file, because that's when fgets
returns NULL
.
Another issue is that you are reading with both fscanf
and fgets
– pick one and stick with it. I recommend fgets
since it's generally easier to get right (e.g., on invalid input it's a lot harder to recover from fscanf
and make sure you don't get stuck in an infinite loop while also not losing any input). Of course you need to parse the integer from str
after fgets
, though, but there are many standard functions for that (e.g., strtol
, atoi
, sscanf
).
Don't use !feof(file)
as the loop condition (see, e.g., Why is “while ( !feof (file) )” always wrong?). If you are reading with fgets
, end the loop when it returns NULL
.
Upvotes: 1