So I am trying to figure out how to use fscanf to read multiple lines from an in file. The in file looks like this:
8
1 8
1 7
1 9
1 8
3 2
3 8
0 0
1 5
2 4
0 0
The first number I want to obtain is going to be the size of an array I will be creating so I will just set it to n(in this example that number being the 8 at the beginning).
The following digits will be as follows: the left most number will tell me what index in my array I will queue the right most number in a list I have created.
The zeros just indicate where I will be terminating.
The way I was attempting to do it thus far is:
fscanf(in, "%d", &n)
//have obtained n
arr[n];
while( fgets(line, MAX_LEN, in) != NULL){
fscanf(in, "%d %d", &x, &y);
//from here I place them in their corresponding arrays
}
Code:
int main()
{
int i, j, k;
scanf ("%d\n", &i);
printf ("%d\n", i);
while (i){
--i;
scanf ("%d %d\n", &j, &k);
printf ("%d %d\n", j, k);
}
}
Execution:
./a.out <input.txt
This is using file redirection. Also check about freopen. If u use this, you no need to worry about fscanf syntax. If you suppose to fscanf only, then there are lots of example in Google. Please refer it.
1) Using fgets() right after fscanf(in, "%d", &n) leaves the first line's '\n' in stdin and only read a short line. Suggest avoid mixing fgets() with fscanf().
2) After using fgets() to read the line (good idea), use sscanf() (or strtol()) to read the numbers, not fscanf()
if (fgets(line, MAX_LEN, in) == NULL) Hanlde_EOF();
if (sscanf(line, "%d", &n) != 1) Handle_BadInput();
arr[n];
while(fgets(line, MAX_LEN, in) != NULL){
if (sscanf(in, "%d %d", &x, &y) != 2) Handle_BadData();
...
}
Related
I'm currently trying writing a program using C (very new to C - only been learning it for 2 weeks), and I wanted to get a string of input from the user by stdin, in which the string has a char, followed by 2 floats (each has space in between). Example would be: "y 2.1 1.1".
My question is how can I obtain and store the 3 inputs, while making sure the first is a char, and the following two inputs are floats?
Stick with sscanf(), but don't forget to check its return value (look here). What really happens for input "y 1u 1" is that sscanf will read and store the char, which is valid, then it will read and store the int 1, which is valid, and then stop, because "u" does not match the format string.
Below is example code (using scanf() rather then fgets() and sscanf()).
char in1;
int in2,in3;
int retval;
/*
char array[100] = {'\0'};
fgets(array, 100, stdin);
retval = sscanf(array, "%c %d %d", &in1, &in2, &in3);
*/
retval = scanf("%c %d %d", &in1, &in2, &in3);
printf("Scanned %d items\n", retval);
printf("Here they come: ");
if(retval > 0) {
printf("%c ", in1);
}
if(retval > 1) {
printf("%d ", in2);
}
if(retval > 2) {
printf("%d", in3);
}
putchar('\n');
How can I obtain and store the 3 inputs, while making sure the first is a char, and the following two inputs are ints?
problem with this code is that there are extra spaces at the very end, and I don't know how to get rid of it.
A simple way to use sscanf() and check if there is extra anything after the scanned variable is to use "%n" to record the location of the scan at that point.
char in1;
int in2, in3;
int n = 0;
sscanf(array,"%c %d %d%n", &in1, &in2, &in3, &n);
if (n > 0 && (array[n] == '\n' || array[n] == '\0')) {
Success(in1, in2, in3);
}
It is always important to check the results of sscanf(). One way is to check its return value which should be 3 here. Unfortunately that does not tell us if anything exist after in3. By setting n == 0 and then testing n > 0, code knows that scanning proceeded all the way successfully to "%n". Code can also test what character the scanning stopped at.
I want to read int from a file
The first line is composed of 1 int and the second of 2
ie
1
2 3
if i do
fscanf(FILE, "%d \n %d %d", &a, &b, &c);
I obtain correctly the 3 numbers
but if i put all the numbers on the same line in the file
ie 1 2 3
I obtain the same result (and that's not what i want)
I want to know : How to force the user to go to a new line in his file ?
Edit :
As it seems unclear to some (i'm sorry for that) i want that the file
1
2 3
Produce the result :
a = 1
b = 2
c = 3
And the file
1 2 3
produce either an error or
a = 1
b = 0
c = 0
You need to read each line into a char buffer using fgets and parse each line with its own sscanf. You can use an extra %s on the end of the format string (and an extra pointer argument to a dummy variable of type char *) to detect whether the line contains extra stuff after the fields you're looking for.
fscanf(FILE, "%d", ...); first scans and discard white space before scanning for int characters. In scanning white-space, both ' ' and '\n' are treated the same, so using '%d' loses the end-of-line.
fscanf(FILE, "\n", ...); and fscanf(FILE, " ", ...); do the same thing: scan and discard any white space. Using "\n" does not scan only for '\n'.
Code could use fscanf(FILE, "%d%*1[\n]%d %d", &a, &b, &c) == 3, to find a '\n' after a, but additional '\n' could be lurking in other places.
The only way using scanf() family to detect a '\n' involves using '%c' or '%[]' or '%n'. It is easier to use fgets() and then parse with sscanf() or strtol().
int Read1and2int(FILE *stream, int *a, int *b, int *c) {
char buf[100];
int n;
if (fgets(buf, sizeof buf, stream) == NULL) return EOF;
int count = sscanf(buf,"%d %n", a, &n);
// Non-numeric or extra data
if (count != 1 || buf[n]) return 0;
if (fgets(buf, sizeof buf, stream) == NULL) return 1;
count = sscanf(buf,"%d%d %n", b, c, &n);
// Non-numeric or extra data
if (count != 2 || buf[n]) return 1;
return 3;
}
So, I'm having problem to read a file using a do-while loop:
#include <stdio.h>
int main(){
FILE* f = fopen("teste.txt", "r");
double i;
do{
fscanf(f, "%lf ", &i);
printf(" %.0lf", i);
} while (fscanf(f, "%lf", &i) != EOF);
return 0;
}
The file is ike that:
1 2 3 4 5
When i run the program, the output is:
1 3 5
Can anyone help me?
You are discarding the result of every second call to fscanf.
In the while condition you call fscanf and check for EOF but you do not use the value of i. Then the next statement is back up the top of the loop , doing another fscanf which reads the next value (and does not check for error).
Also, you have an infinite loop if the file contains any text which is not a valid double.
The loop should be:
while ( fscanf(f, "%lf", &i) == 1 )
{
printf(" %.0f", i);
}
It should be:
#include <stdio.h>
int main() {
FILE* f = fopen("teste.txt", "r");
double i;
fscanf(f, "%lf ", &i);
do {
printf(" %.0lf", i);
} while (fscanf(f, "%lf", &i) != EOF);
return 0;
}
after fscanf(f, "%lf ", &i);, f contains 1. Now after fscanf(f, "%lf", &i) != EOF, f contains 2. You are not printing that 2 and after next fscanf(f, "%lf ", &i);, f will contain 3. In short you are calling fscanf twice in every loop and printf only once.
I'm sorry, I've done something similar to this before and I'm sure I'm over complicating this, but could someone help me understand whats wrong? I've only known java previously, but I'm getting familiar with C.
I have tried 3 different ways from searches online, the one not commented out is the one I'd prefer to use. It's printing out the right amount of numbers in data.txt but it only prints out the number 1. I thought the c = scanf inside the while would give me a different result each time.
I also tried just reading in the numbers as a char since I'm not doing any math, but I got a bunch of funky symbols.
input:
./a.out < data.txt
data.txt contents:
0 2 2
0 6 1
0 7 4
1 7 5
0 8 2
0 8 9
1 15 13
c file content:
#include
#include "queue.h"
int main(void)
{
/*
char c = scanf("%c", &c);
while (c!= EOF)
{
printf("%c", c);
c = scanf("%c", &c);
}//while
*/
int c = scanf("%d", &c);
while (c!= EOF)
{
printf("%d", c);
c = scanf("%d", &c);
}//while
printf("\n");
/*
char c;
//char **argv
FILE *infile;
infile=fopen(argv,"r");
while (!feof(infile))
{
fscanf(infile, "%c", &c);
printf("%c", c);
} // while
fclose(infile);
*/
return 0;
}
You should use a different variable for checking the result of scanf than for storing the value read. As you have it now, you immediately overwrite the read value with the scanf result.
Also, it is better to check for success than to check for EOF, as if there is text entered you will go into an infinite loop.
int x = scanf("%d", &c);
while ( x == 1 )
{
printf("%d", c);
x = scanf("%d", &c);
}
Obviously this can be condensed:
while ( 1 == scanf("%d", &c) )
printf("%d", c);
I have to read "N" int from .txt file and place each one to an array X[i]
But the problem is, I'm not suposed to know how many int are in the txt. The code has to work for every txt following this model
5 4
1 2 3
1 3 4
2 3 5
4 5 5
So I have, in the first line, the second number (4 in the exemple) the number of int in the txt will be N=4*3 (4 lines with 3 numbers (ALWAYS second number*3)) + 2 (first line)
The only code I know how to do is when I know how much numbers, like
int t[14] // I know there are 14 numbers on the .txt
while(fgets(buf, sizeof(buf), fp)) {
int result = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5], &t[6],&t[7],&t[8],&t[9],&t[10], &t[11],&t[12],&t[13]);
if (result <= 0) break; // EOF, IO error, bad data
for (r=0; r<result; r++) {
if (i >= sizeof(X)/sizeof(X[0])) break; // too many
X[i++] = t[r]; //put them in the X[MAX]
}
}
And I need to read every number cause like in
2 3 5
I'll place 5 to a array[2][3]
How I am supposed to do this?
Can someone show me an example???
Thanks!
A simple template:
int a, b, i;
int *N;
if(fscanf(fp, "%d%d", &a, &b) != 2) { /* Read the first 2 integers */
/* Unable to read in 2 integers. Handle error... */
}
N = malloc(3 * b * sizeof(int)); /* Allocate enough space */
for(i = 0; i < 3*b; ++i) {
if(fscanf(fp, "%d", &N[i]) != 1) { /* Read numbers one-by-one */
/* Input may not be enough. Handle error... */
}
}
/* Now you have (3*b) integers stored in N */
/* after operations completed... */
free(N);
There is no need to read in line-by-line and guess how many numbers are there. Just call fscanf() again and again since your input is delimited by space characters and newline characters.