Need help resolving weird fscanf issue - c

I am trying to read from a file line by line by running it through a while loop which is instructed to exit once EOF has been reached. But for some reason once the last line has been read and the while condition is checked again the program just freezes.
This is my code:
char character1;
int number1;
while(fscanf(file,"%s %d",&character1, &number1) != EOF){
//printf("%s %d\n",character1,number1)
}
My files contents:
A 1
B 2
C 3
D 4
E 5
Output:
A 1
B 2
C 3
D 4
E 5
| <---Blinking terminal pointer currently there
Can anyone help me figure this out?
EDIT: I am not opening/closing the file in main(), I am doing it in another function, could this be causing a problem?

Improve the condition checking on the while loop. The fscanf() can produce more results that EOF or a positive number. It can also return a positive number when an end-of-file occurs after conversion has begun. Meaning that you have something going wrong with a conversion and so the data is still there the next time you loop around to get more data from the stream. So you are stuck infinitely failing to convert that same failed conversion.
You are looking for 2 input items so check that the fscanf() has found 2 input items in order to continue looping.

The problem is that your fscanf reads the \r or \n in the end of every line. Just creates a buffer to ignore it and will be fine. I did the following and it worked smoothly.
char character1;
int number1;
char buffer[2]; // will read the end of line
while(fscanf(file,"%c %d",&character1, &number1) != EOF){
fgets(buffer, 2, file);// does the job
printf("[%c] [%d]\n",character1,number1);
}

Related

Looping fscanf causing additional loops (C language)

I am facing problems looping a fscanf. As in the code below (focus on the part where the while loop starts), I am looping the fscanf until it reached EOF. As you can see from the 2nd part below, the .txt file to fscanf from has only 6 strings,so the fscanf should only loop 6 times and then it reaches EOF. However, as you can see from the program output (2nd part belowe), the fscanf is looped 7 times. Since my program displays the missilenames in reverse order, I assume the while loop looped 1 additional time at the end, resulting at the blank line output on the first line of 3rd picture.
Can someone tell me how to fix this problem pls?
C CODE
while(fscanf(readmissiles,"\n %s \n",missilename)!=EOF)
{
missilename=malloc(20*sizeof(char));
insertvalue(LL,missilename);
missilenum++;
}
TEXT FILE TO FSCANF FROM
single
splash
single
V-Line
h-line
Single
OUTPUT/DISPLAY
/there is a blank line displayed before the Single/
Single
h-line
V-Line
single
splash
single
7
fscanf returns the number of elements scanned or EOF in case of error or end of file is reached before it could match anything. On the last loop fscanf returns 0 - it did not scan the element but it scanned \n, so it returns 0. Do:
while(fscanf(readmissiles, "%s", missilename) == 1)
Loop until there is one element scanned.

How to slice/index data in c

I am trying to learn C and have recieved a homework assignment to write code which can read data from a .txt file and print out particular lines.
I wrote the following:
#include <stdio.h>
void main() {
char str[5];
FILE *fp;
fp=fopen("data.txt","r");
int i;
for (i=1;i<=5;i++){
fgets(str,5,fp);
printf("%d \n",i);
if (i==1||i==3||i==5) {
printf("%s \n \n",str);
}
}
}
The file data.txt is just the following:
3.21
5.22
4.67
2.31
2.51
1.11
I had read that each time fgets is run, the pointer is updated to point to the next line. I thought I could keep running fgets and then only print the string str when at the correct value for i (the line I want output on the console).
It partially worked, here is the output:
1
3.21
2
3
5.22
4
5
4.67
Process returned 8 (0x8) execution time : 0.024 s
Press any key to continue.
It did only print when i had the correct values, but for some reason it only printed the first 3 lines, even though fgets was supposed to have been run 5 times by the last iteration, and so the pointer should have been reading the last line.
Can someone explain why the pointer did not update as expected and if there is an easier way to slice or index through a file in c.
You need to account for (at least) two additional characters, in addition to the numbers you have in the file. There is the end-of-line delimiter (\n on UNIX/Mac, or possibly \r\n on Windows... so maybe 3 additional characters), plus (from the fgets documentation):
A terminating null character is automatically appended after the characters copied to str.
A lot of the C functions that manipulate character arrays (ie. strings) will give you this extra null "for free" and it can be tricky if you forget about it.
Also, a better way to loop over the lines might be:
#define MAX_CHARS 7
char buf[MAX_CHARS];
while((fgets(buf, MAX_CHARS, fp)) != NULL) {
printf("%s\n", buf);
}
It's still not the best way to do it (no error checking) but a little more compact/readable and idiomatic C, IMO.

Storing every newline into two zero from a file using C language

Question Updated with my code.
I have a file as the format below. Every line contain a integer and a float.
12 2.0
11 1.1
3 3.0
I want to store the first data in each line into variable A, and second data into variable B.
At the beginning, I use fscanf to do this as below
while (1) {
int exit;
exit = fscanf(fp, "%d%f", &A, &B);
if (exit < 2) break;
}
If I print the result of A and B, it would be
12 2.0
11 1.1
3 3.0
But actually I want to store the newline as 2 zero, for example:
12 2.0
11 1.1
0 0
3 3.0
Some website suggest using fgets/fgetc to read through the newline. But I cannot understand how fgets/fgetc can store integer and float into var A and B.
Thanks for you attention.
For each line, call fgets() with a large enough buffer to hold any line you reasonably expect. The instead of fscanf, call sscanf on the string, with exactly the same parameters. So the programs should now work identically, except it is separating out the IO from the parse.
Now you cat make the parse more complicated. if the line is blank (just whitespace), then the two values are zero, If it is not whitespace, call sscanf and attempt to parse as before. If both fail, you have malformed input, so report an error.
Also, fgets will return null when it runs out of input. So you don't need to use a parse fail to terminate the read any longer.

How to use fgetc() to capture only letters and storing input to an array

I am trying to write an indexing program where it will take input from the user and store it into an array then keep counting the occurrence of words for example.
user enters: hello##world I,I,I am##!stuck201
hello 1 occurred 1 time
world 1 occurred 1 time
I occurred 3 times
am occurred 1 time
stuck occurred 1 time
So as you can see it will count anything that contains letter(s) separated by anything as a word.
(I am confused on how to go about checking the input for anything other than letters, I was thinking of using ASCII codes but there has to be a better way, if you could just set me in the correct direction for this, Thank you much.)
Before I began the program I was trying to get I/O working and I am having difficulty. The actual program will require me to use 2 dimensional arrays, but if you could help me with this snippet of code that will be appreciated thanks.
#include <stdio.h>
int main()
{
char array[64];
int i=0, j, input;
printf("Please enter an input:");
input==fgetc(stdin);
while(input != " ")
{
array[i]==input;
i++;
input==fgetc(stdin);
}
for(j=0;j<10;j++)
{
printf("You entered:%c",array[j]);
}
}
Upon compilation it gives me a warning "12:14 warning: comparison between pointer and integer"
Output of this code:::
Please enter an input: (I type input) ehehasd world hello (enter)
then it just sits at blank cursor and I have to exit using CTRL C
I want this snippet of code to just take input from user that is separated by a space store it into an array then print out what the user entered. What am I doing wrong?
Check isalpha, it has some fineprints about what it will consider a letter, but it may work for your case.
Another way to do it, if you don't want to do the loop yourself is to use regular expressions. It is fairly easy to make a regex that returns only sequences of letters.
The line (which appears twice in the code):
input==fgetc(stdin);
makes a comparison, not an assignment. Use:
input = fgetc(stdin);
Your line:
while(input != " ")
is incorrect and is the source of the compiler warning. You are comparing a string with a character. You probably intended to use:
while (input != ' ')
and since you could encounter EOF, you probably should use:
while (input != EOF && input != ' ')
You could sensibly use #include <ctype.h> and then:
while (isalpha(input))
which automatically handles EOF (it's a valid input to isalpha(), but returns false; EOF is not an alphabetic character).
Your final loop should probably be:
for (int j = 0; j < i; j++)
(assuming you have a C99 or more recent compiler — if not, declare j outside the loop as now). This only outputs words that have been entered. Otherwise, you'll be printing undefined gibberish.
You'll need to upgrade the code to handle multiple words in the input. At the moment, it stops at the end of the first word (assuming you fix the other problems that I've identified).
Use isAlpha() to test is it is a letter, look here

How To Read Input From Test Case File in C

Currently i am enrolled in NPTEL course. There i need to make c program as assignment.
Qusetion is in this format :-
Write a program that reads numbers which are in the range 0 to 100, till it encounters -1. Print the sum of all the integers that you have read before you encountered -1
INPUT:
A sequence of integers separated by whitespace. There may be other integers following -1.
How do i read input from test case file? plz help
I have used following code :-
while((n=scanf("%d",&n1))!=EOF)
{
printf("%d",n);
}
Loop is iterating properly ie if test case 1 has 5 input its running for 5 times. If test case 2 has 2 input hen iterating 2 time. But it is unable to read input . Please Help.
You're printing n which is the number of items read. You need to print n1.
EDIT:
Your check for the while loop is incorrect. You need to check the value that is read i.e. n1 but once again, you're using the value of n to check for EOF. You should be checking for -1 as well since that's what you want right?

Resources