Repetition of final line when computing sum? [duplicate] - c

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 9 years ago.
I'm taking my first programming class ever this year and I'm slight confused on this. I'm trying to learn the fopen and fclose functions currently.
My code is
int main(void)
{
FILE *input; /* Pointer to the input file */
double values;
double sum;
input = fopen("data.dat", "r"); /* Prepare file for input */
sum = 0;
while (!feof(input))
{ fscanf(input, "%lf", &values);
sum = sum + values;
}
printf("The sum of the values is %f\n", sum);
fclose(input);
return 0;
}
When I compile this to get the sum, the last value of the data.dat file is counted for twice.
I was wondering how I could fix this.
Thanks!

You should not use while(!feof(...)) because it's always wrong. Why?
It will, as you found out, loop one more time than you expect. That happens because the semantics of feof() are not what you think: that is, they are not to check if the next read will reach the end of file. Instead, feof allows you distinguish between a read error and the end of the file after you get a zero from a read (or some other similar call).
The solution to your problem is easy: use the functions you call properly. fscanf returns a value - you should find out what that value is and, more importantly, what it means.

Related

I can't read and display txt file [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed last month.
The community is reviewing whether to reopen this question as of 22 days ago.
I'm trying to read a file from txt docs and display the data, but when I run the code, it displays nothing and just shows like this:
enter image description here
I'm not sure where the problem is with my code, but perhaps the problem is because I need to display 4000 columns of data so the program cannot read and display it. I tried to use another sample txt with 10 columns of data and the code worked but not with 4000 columns of data.
This is my code :
char str [101][101];
FILE *fin = fopen ("test.txt", "r");
int count = 0;
while (!feof(fin)){
fscanf (fin, "%s", str[count]);
count++;
}
fclose(fin);
for (int i = 0 ; i < count ; i++){
printf("%s\n", str[i]);
}
This is data I want to read and display (4000 columns data)
Bali
Paris
Japan
Nepal
India
Rusia
Malaysia
Thailand
England
etc....
Thank you in advance!!
I haven't tried to run the code.
You read a file line by line and put every line within str. However, str can only contain a maximum of 101 lines, with each iteration not exceeding 100 chars.
Increase the value of str to at least 4000.
str[4500][101]
EDIT:
The question has been flagged as duplicate; however, the problem here is linked to how the C language works.
In this example, we have a static two-dimensional array for which C reserved some memory on the stack. As C tries to use more memory than allocated, the O.S. will inform the process that it does not have access to the location. Which makes C raise an exception at runtime.
I think bringing this precision to those who learn C is essential to avoid confusion.

How to take values from a file, apply an equation to those values, and write them to file in c

How do I take values from a file, apply an equation to those values, and write them to file in c?
It seems simple, what I've tried just writes the same number as many times as I have samples. I would like to write a file with the new values.
printf("Enter the number of sample values in the file minus 1.\n"); //11025
scanf("%d",&n);
printf("using %d sample values.\n",n);
// fseek(filein, "%lg", SEEK_SET);
for ( c = 0 ; c <= n ; c++ )// // Convert a reading (which goes from 0 - 65536) to a value (-1 - 1):
// float voltage = sensor * (1 / 65536.0);
{
fseek(filein, n, SEEK_SET);
fscanf(filein, "%lg", var);
sum = var * (maxy / 65536.0);
//todo?
//todo?
fprintf(fileout,"%lg\n",sum);
}
getchar();
fclose(filein);
fclose(fileout);
return 0;
}
return 0;
} ```
This answer is based on the code posted at Code Review.
The fseek() is part of the problem because it keeps resetting to the beginning of the file.
You could do this without the use of fseek(), the file will open to the beginning and you're reading binary data.
You should probably use fgets() rather than fscanf() to read each line separately and the convert the text using sscanf().
The format you want in the fprintf() and fscanf() is just %g or %G, the %l is for long integers.
Since the code is already using stdlib.h use the macros EXIT_SUCCESS and EXIT_FAILURE rather than 0, 1, SUCCESS or ERROR. Note that in C programming SUCCESS should be 0 and ERROR should be 1.
This program desperately needs functions, you are repeating code in too many places.
The for loop is a bug waiting to happen because it can attempt to read past the end of the file. A while loop that incorporates both the counting of lines and while not end of file would be much better.
Declare variables as needed.

Implementation of a c counter

I wrote a c program to count the number of time the word "printf" occurs in a specific file (here "document.c"). "document.c" has multiple lines of code. What I have done is I started with a while loop to iterate over every lines of the file and then I am reading the characters of each lines inside the for loop by using the function strstr.
It does not print anything with my current code. Moreove, I think there is some other minor issues because in an older version it used to print but not correctly, it printed a number much more larger than the actual number of "printf" in the document.
I am also novice in c.thank you!
int counter() {
FILE * filePointer;
filePointer = fopen("document.c", "r");
int counter = 0;
char singleLine[200];
while(!feof(filePointer)){
fgets(singleLine, 200, filePointer);
for (int i = 0; i < strlen(singleLine); i++){
if(strstr(singleLine, "printf")){
counter++;
}
}
}
fclose(filePointer);
printf("%d",counter);
return 0;
}
You're iterating over each character in the input line, and then asking if the string "printf" appears anywhere in the line. If the line contains 5 characters, you'll ask this 5 times; if it contains 40 characters, you'll ask this 40 times.
Assuming that you're trying to cover the case where "printf" can appear more than once on the line, look up what strstr() returns, and use that to adjust the starting position of the search in the inner loop (which shouldn't iterate over each character, but should loop while new "hits" are found).
(Note to up-voters: I'm answering the question, but not providing code because I don't want to do their homework for them.)

Reading from a binary file using fread() displays additional characters [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 8 years ago.
My question is about this fread() function that seems to be confusing for the time being. I create a binary file and put inside of it the values 1,2 and 3. And then I try to read the file and when I do using fread() it shows it like 1233 not 123.
#include <stdio.h>
#include <stdlib.h>
main ()
{
int x=1,y=2,z=3,i,j;
FILE *f;
f=fopen("Werid.bin","wb");
fwrite(&x,sizeof(int),1,f);
fwrite(&y,sizeof(int),1,f);
fwrite(&z,sizeof(int),1,f);
fclose(f);
f=fopen("Werid.bin","rb");
if (!f) perror("X");
while(!feof(f))
{
fread(&j,sizeof(int),1,f);
printf("%d",j);
}
fclose(f);
}
Why?
Change this
while(!feof(f))
to
while(fread(&j,sizeof(int),1,f) == 1)
From linux feof() manual
The function feof() tests the end-of-file indicator for the stream pointed to by stream, returning nonzero if it is set. The end-of-file indicator can only be
cleared by the function clearerr().
The feof() will return true after you try to call fread() at the end of file i.e. after you read the last number, you will need to call fread() again to set the end-of-file indicator.
So the loop will be executed one more time after the last read, and since it does not read anything but rather returns an error, it does not change the value of j either, so the previous value 3 is printed again.

Looking for a good way to read data from file in C

this is my first question in this site, and I've just started programming, please be patient with me.
I'm having some trouble with this code to read strings and intergers from a file, they are separated by a semicolon ";" and it starts with the number of lines. The file is something like this:
13;
A;15;B;1;0;0;0;
A;9;C;0;3;2;0;
A;9;D;0;4;0;2;
A;3;E;2;3;2;0;
A;7;F;5;5;3;1;
A;5;G;5;7;6;0;
A;13;H;0;0;0;0;
A;1;I;8;1;0;0;
A;1;J;2;2;1;0;
A;6;K;7;3;2;0;
A;5;L;2;4;3;0;
A;12;AA;0;3;2;0;
A;9;BA;0;1;0;0;
What I tried to do was to create a function that would receive a file pointer (fp) and the number of lines that was read in the main function. It would read the file and save the intergers and strings in matrices :
#include<stdio.h>
#include<stdlib.h>
char timesjogos[100][2][100];
int golsjogos[100][3];
int faltasjogos[100][3];
int camajogos[100][3];
int cverjogos[100][3];
int ReadGames(FILE *caminho,int njogos){
printf("starting to read jogos.\n");
int i=0;
while(fscanf(caminho, " %[^;];%d[^;];%[^;];%d[^;];%d[^;];%d[^;];%d[^;];",
timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1], &golsjogos[i][1],
&faltasjogos[i][0], &camajogos[i][0], &cverjogos[i][0]) == 7)
{
if(i < njogos)
i++;
else
break;
}
}
int main()
{
FILE *fp;
int nbets;
fp = fopen("jogos.txt", "r");
if (!fp){
printf ("Error trying to open file.");
}
fscanf(fp, " %d[^;];", &nbets);
ReadGames(fp, nbets);
}
My doubts are about the %[^;]; I used to read each string up to the ; , should I use %d[^;] for the intergers? What is the correct way to do it?
Also, I'm using global variables to save the information read, the problem is that they can be not large enough to save huge amounts of lines (my professor made a 24180 lines file to test our codes). I was thinking about using the number of lines it gives in the first line to make pre-sized matrices inside the function, but how can I return or save it after the function ends?
I'm sorry for the huge code, but I wanted to show all the details. I would be very thankful for your more experienced help :D
The %[^;] notation reads a string consisting of any number of non-semicolons. The parsing stops when a semicolon is encountered. With numbers, the parsing stops at a semicolon anyway; the semicolon is not a part of the representation of a number.
Your use of %d[^;] means that fscanf() is looking for an integer (%d), then an open square bracket, caret, semicolon and close square bracket. These don't appear in the input, of course, so the scanning fails.
Therefore, your input loop should probably be:
while (fscanf(caminho, " %[^;];%d;%[^;];%d;%d;%d;%d;",
timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1],
&golsjogos[i][1], &faltasjogos[i][0], &camajogos[i][0],
&cverjogos[i][0]) == 7)
{
...
}
You might prefer to specify a maximum length for the %[^;] conversion specifications; %99[^;] would be appropriate since the third dimension of timesjogos is 100. There's an off-by-one difference between the length specified and the length used (enshrined because of ancient history; it was that way before the first C standard, and the C standard codified existing practice).

Resources