Extra Line read from file - c

I'm trying to read from a text file and store it into an array, but my last array is filled with garbage, is there any way to fix it? For reference, I don't need that last line of values, but I can't seem to find a way to get rid of it.
int k;
char string[100];
for(k = 0; k < MAX_STATIONS; k++){
if (fgets(string, sizeof(string), fp) == 0){
break;
}
fscanf(fp,"%d %f %d %d %d %d %d %f %f", &stationInfo[k].stationID, &stationInfo[k].temperature, &stationInfo[k].year, &stationInfo[k].month, &stationInfo[k].day, &stationInfo[k].hour, &stationInfo[k].minute, &stationInfo[k].location.latitude, &stationInfo[k].location.longitude);
printf("%d %1.2f %d %d %d %d %d %f %f\n", stationInfo[k].stationID, stationInfo[k].temperature, stationInfo[k].year, stationInfo[k].month, stationInfo[k].day, stationInfo[k].hour, stationInfo[k].minute, stationInfo[k].location.latitude, stationInfo[k].location.longitude);
}
EDIT: I've realized that using this method, I don't actually get the first line of my file read. How could I fix this?

You should check the return value of fscanf it returns the number of read fields and ignore (or print a warning) lines which are incomplete. Another idea would be to check whether 100 chars are really long enough to hold the longest line (+ EOS).

Related

How to read an unknown quantity of integers from console?

I have entries like these:
0 5 260
1 0 -598
1 5 1508
2 1 -1170
I don't know previously how many (console) inputs I'll get, so I have to read until there are no entries left.
I started with a code like this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)!=EOF){
// do stuff here
}
But it never stops asking for new input.
Then, I saw people in other threads suggesting this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)==1){
// do stuff here
}
In this case, it doesn't even enter the while.
Does anyone know what I'm doing wrong?
An approach: Continue asking for input until the input is closed (EOF) or some problem is encountered. (Invalid line of input)
The below uses fgets() to read a line.
Then, " %n" to detect where scanning stopped. If scanning does not reach %n, n will still have the value of 0. Otherwise it gets the offset in buffer where scanning stopped, hopefully it was at the null character '\0'.
char buffer[100];
while (fgets(buffer, sizeof buffer, stdin)) {
int n = 0;
sscanf(buffer, "%d%d%d %n", &a, &b, &c, &n);
if (n == 0) {
fprintf(stderr, "3 int were not entered\n");
break;
}
if (buffer[n] != 0) {
fprintf(stderr, "Extra input detected.\n");
break;
}
// do stuff here with a,b,c
}
There are many approaches to solve this issue.
while(scanf("%d %d %d", &a, &b, &c)==1)
means that "if scanf() successfully read just one value, proceed in the loop."
Therefore, if you enter something like 0 junk, the scanf() read just 1 data and will enter the loop once.
Try using
while(scanf("%d %d %d", &a, &b, &c)==3)
to have it enter the loop when scanf() successfully read three values, which is what expected.

How to use scanf in for loop

Whenever i try to read input with
for (int i = 1; i <= 10; ++i) {
scanf("(%c, %d, %d, %d)",&charv,&intv1,&intv2,&intv3);
}
I only get to scanf() once. What is the problem ?
Input -> (P, 1, 2, 3)......(P, 2, 3, 12)
Your usage of scanf() is wrong. You have to provide the pointer to the variable to store the value read by scanf(). You need to use it like below
for (int i = 1; i <= 10; ++i) {
scanf("%c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
}
EDIT:
Point 1: The supplied format string should exactly match with the input. Otherwise, scanf() will fail. If your input is not of format (<char>, <int>.... , it will fail. Either of missing (, ), , will cause mismatch in the supplied format string with the input and make scanf() to stop scanning. It's strongly recommended to check the return value of scanf() to ensure it's success.
Point 2: To avoid reading the \n stored by previous ENTER<\kbd> key press, you should add a leading space before %c. So, you can use something like
scanf(" %c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
^
|
Notice here
scanf("(%c, %d, %d, %d)",&charvar,&intvar1,&intvar2,&intvar3);
should be
scanf(" %c, %d, %d, %d",&charvar,&intvar1,&intvar2,&intvar3);
Note the space before %c which ignores newline if it exists. If your input is not separated by commas
scanf(" %c %d %d %d",&charvar,&intvar1,&intvar2,&intvar3);
Like Sourav Ghosh and Gopi said, scanf will not work properly with this syntax
scanf("(%c, %d, %d, %d)",&char,&int,&int,&int);
It should be
scanf("%c %d %d %d",&char,&int,&int,&int);
But you can read a string first, and then use sscanf.
Try this code:
char ch;
int a, b, c, i;
char teste[256];
for(i=0;i<10;i++){
fgets(teste, 256, stdin);
sscanf(teste, "(%c, %d, %d, %d)", &ch, &a, &b, &c);
printf("%c %d %d %d\n", ch, a, b, c);
}

selective input using scanf

From an input of n numbers(value of n is known) separated by spaces,
eg(here n is 6):
3 5 8 9 13 2
If I wish to accept only the 2nd and the 5th number and ignore the rest, how do I do it using scanf?
I found accepting the numbers in an array and using only the required ones a bit redundant, so I'm looking for a smarter alternative.
If the knwon number n is a fix number (n=6 always)
then you can use the following scanf
int a2, a5;
scanf("%*d %d %*d %*d %d %*d", &a2, &a5 );
scanf("%*d%d%*d%*d%d%*d", &firstNumber, &secondNumber);
Try this.
%*d reads the value, but ignores it in the name of good will.
Try this
int num,number1,number2;
for(int i = 0; i < 6; i++)
{
scanf("%d", &num);
if(i == 1)
number1 = num;
if(i == 4)
number2 = num;
}
I would read every number using scanf. Read not required ones in some temp variable and others in array or any variable (as required)
scanf("%*d %d %*d %*d %d %*d", &i, &j)
int v[6];
scanf( "%d %d %d %d %d %d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5] );
v[1] and v[4] contain the answers from your example.

How to read from .txt in C

I have to read from a .txt like this (1. - txt line)
1 2
1 2 3
1 3 4
but I have to read like: "1" first line, attribute to x[0], "2" first line attribute to x[1]. I know how to do that but the problem is that I have to skip to the line 2 and do the same, but it doesn't work.
So It'd be like
x[2]=1. x[2]=2, x[3]=3, x[4]=1, x[5]=3, x[6]=4
Is there a way for me to do it???
Thanks!
Let me try to be more especific
1 2 1
2 3 1
3 4
Imagine this is a txt file where 3. 2. and 1. are first, second and third line. I have to read each number on each line and assign to a vet[MAX];
I can do it, but only with the first line. I don't know how to skip to the second one
My code
#include <stdlib.h>
int main (void)
{
char buf[1024];
int numeros[8];
FILE *fp = fopen("teste.txt", "r");
if(fp == NULL)
return EXIT_FAILURE;
while(fgets(buf, sizeof(buf), fp)) {
if(buf[0] == '\n')
continue;
sscanf(buf, "%d %d %d %d %d %d %d", &numeros[0], &numeros[1], &numeros[2], &numeros[3],&numeros[4], &numeros[5], &numeros[6]);
}
fclose(fp);
printf(" \n %d \n %d \n %d \n %d \n %d \n %d \n %d", numeros[0], numeros[1], numeros[2], numeros[3],numeros[4], numeros[5], numeros[6]);
}
the output
3
4
1
131072
2685712
302692880
4798692
Process returned 53 (0x35) execution time : 0.016 s
Press any key to continue.
And I wanted
1 2 2 1 2 3 1 3 4
Assuming your double use of x[2] is a typo, and assuming the line numbers are not really in the file, all you need is to loop doing:
fscanf(file, "%d", &x[i++]);
until it fails. So remember the check the return value, if it isn't 1 it failed to find a number to convert and store, and you should stop.
Of course, this assumes that x has space enough, and that i is initialized to 0.
Use the result of sscanf().
You will likely get 2 or 3 each loop. This means 2 or 3 int were successfully scanned. This number can then be used to determine saving the int in numeros[].
int i=0;
while(fgets(buf, sizeof(buf), fp)) {
int t[7];
int result = sscanf(buf, "%d %d %d %d %d %d %d", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5], &t[6]);
if (result <= 0) break; // EOF, IO error, bad data
for (int r=0; r<result; r++) {
if (i >= sizeof(numeros)/sizeof(numeros[0[)) break; // too many
numeros[i++] = t[r];
}
}

Reading a file and converting the input into two arrays

I want to read a file containing numbers in two columns.
1 2
3 4
5 6
7 8
I want to place the numbers in the first column into one array, and the ones in the second column into another array. Both of these arrays will always have the same amount of elements. The maximum number of elements permitted in this program is 100.
Here's what I have so far. This just reads in the elements as regular int and prints them out.
while (!feof (filereader))
{
printf ("%d %d\n",col_one,col_two);
fscanf (filereader, "%d %d", &col_one, &col_two);
}
So how do I place the numbers in the first column from the file into one array and the numbers in the second column into an array?
int array1[100];
int array2[100];
int i, size = 0;
while (size<100 && fscanf (filereader, " %d %d", &array1[size], &array2[size])==2)
{
size++;
}
for (i=0; i<size; i++) {
printf("array1[%d] = %d, array2[%d] = %d\n",
i, array1[i], i, array2[i]);
}
add space at the beginning of the format specifier of scanf " %d %d" this will avoid the problem of newlines in your file
Since you've got a maximum size, it's pretty easy. Just define the arrays like so:
int firstArray[100];
int secondArray[100];
int size = 0;
Then do your loop, incrementing the index for each line:
while (!feof (filereader))
{
fscanf (filereader, "%d %d", &col_one, &col_two);
firstArray[size] = col_one;
secondArray[size] = col_two;
size++;
}
Maybe also think about making sure size < 100 in case the file is too long.

Resources