fscanf stops reading file without any reason - c

I am writing a little program for reading a file formatted like that :
2 2
1.0 2.0
5.0 5.1
6.5 3.1
5.1 2.3
3 1
4 1 2 3 5 2
1 4 5 2 6 5
1 4 5 2 3 6
I am using fscanf to read the first two integers and allocate an array to store all four float that follows. It works fine. But when the "cursor" arrives to the line that contains integers "3 1", it stops working for any reason...
float *c = NULL;
float **coord = NULL;
f = fopen("mesh.dat", "r");
if( f != NULL ){
/* the first two integers */
fscanf(f, "%d %d", &n1, &n2);
n = n1*n2;
c = malloc(2*n*sizeof(float));
coord = malloc(2*sizeof(float *));
for(i=0; i<2; i++){ coord[i] = &c[i*n1]; }
/* reading all coordinates */
for(i=0; i<n; i++){ fscanf(f, "%f %f", &coord[0][i], &coord[1][i]); }
/* reading the two integers */
fscanf(f, "%d %d", &n, &t);
printf("n = %d, t = %d\n", n, t);
}
fclose(f);
The program stops here. Because it doesn't read the integers "3 1".
Any idea ?? I'm tearing out my hair trying to understand...

This line:
fscanf(f, "%d %d", &n1, n2);
Should be
fscanf(f, "%d %d", &n1, &n2);

Related

Why are these integer values in my array changing?

I'm trying to read in data from a file and it seems to be read in correctly, however when I print the data 2 of the values change to 3. I'm very confused why this is happening. The file that is being read in looks like this:
John 7 0 1 3 2 0 1 1
Jack 3 4 4 1
Jane 5 3 2 3 0 4
Jenny 6 4 2 1 3 0 4
Jim 2 0 0
Joanna 4 1 2 4 2
The first number is just used to identify how many following numbers there are. For the first line, the first print statement reads it in as 0132011, but when the second print statement is executed it prints out 0132441. This also happens in the line with Jenny. It is read in as 421304, but printed out as 421300.
int* philRequests[numPhilosophers];
int numRequests[numPhilosophers];
for(int i = 0; i < numPhilosophers; i++){
fscanf(fp, "%s", buff);
strcpy(names[i], buff);
fscanf(fp, "%d", &numRequests[i]);
philRequests[i] = (int *)malloc(numRequests[i] + 1); //allocates memory by the number of requests each phil will make
for(int x = 0; x < numRequests[i]; x++){
fscanf(fp, "%d", &philRequests[i][x]);
printf("\nAdding %d to %d %d", philRequests[i][x], i, x);
}
fgets(buff, 255, (FILE*)fp); //moves on to next line
}
//displaying what was just read in
for(int i = 0; i < numPhilosophers; i++){
for(int x = 0; x < numRequests[i]; x++){
printf("\nReading %d from %d %d", philRequests[i][x], i , x);
}
printf("\n");
}
Looks like an issue with overwriting memory because you aren't allocating enough space in your malloc call. Malloc allocates the specific number of Bytes you ask for. You ask for (numRequests[i]+i) Bytes. But you are actually looking for (numRequests[i]+i) pointers to int.
Try something like
philRequests[i] = malloc((numRequests[i] + 1)*sizeof(int*));

Get number after colon in C

I'm trying to read the numbers after a colon and store the value in a variable, but when I print it, it prints a random 6 digit number. I only need to store the value, not the 'ms' or 'degrees'.
For example, the text file is similar to this, but repeats for 100 set of values:
time: 20 ms
temperature: 50.5 degrees
lightvalue: 30
value1: 0.59
value2: 1
value3: 0
----------------------
time: 40 ms
temperature: 37 degrees
lightvalue: 10
value1: 1.57
value2: 0
value3: 1
----------------------
I want to store each number in a separate variable.
Here is part of my code:
int time[10];
double temperature[10];
int lightvalue[10];
double value1[10];
int value2[10];
int value3[10];
for (int i = 0; i < 100; i++) {
fscanf(infile, "time: %i", &time);
fscanf(infile, "temperature: %d", &temperature);
fscanf(infile, "lightvalue: %i", &light);
fscanf(infile, "value1: %d", &val1);
fscanf(infile, "value2: %i", &val2);
fscanf(infile, "value3: %i", &val3);
//how to skip the "---------------" line?
}
Your code contains several errors. You have used different variable names in iteration. You used wrong specifiers.
for (int i = 0; i < 2; i++) {
fscanf(infile, "time: %d %*s\n", &time[i]);
fscanf(infile, "temperature: %lf %*s\n", &temperature[i]);
fscanf(infile, "lightvalue: %i\n", &light[i]);
fscanf(infile, "value1: %lf\n", &val1[i]);
fscanf(infile, "value2: %i\n", &val2[i]);
fscanf(infile, "value3: %i\n", &val3[i]);
fscanf(infile, "%*s\n"); // to skip the "---------------" line
}
To skip rest of the line, you may use %*s which will match the unused string.

Space separated integers to array

I'm new to C, and I have an assignment where I get an input of n space separated integers, and q integers separated by new lines. I would like to save the n integers in an array a, and the q integers in another array m.
This is my code so far and it works as expected for m, but the elements in a are pretty random. How can I save the space separated integers into an array?
int main() {
// The code
int n, q;
int a[n];
int m[q];
scanf("%d %d", &n, &q);
for (int i=0; i<n; i++) {
scanf("%d", &a[i]);
}
for (int i=0; i<q; i++) {
scanf("%d", &m[i]);
}
// Troubleshooting
for (int i=0; i<n; i++) {
printf("%d ", a[i]);
}
printf("\n");
for (int i=0; i<q; i++) {
printf("%d\n", m[i]);
}
return 0;
}
For example when I input:
1 2 3 4 5 6
0
1
2
3
4
5
I get:
4 5 3 4 5 6
0
1
2
3
4
5
I'm not sure but when i run your code i get segmentation error because instead of:
int n, q;
int a[n];
int m[q];
scanf("%d %d", &n, &q);
You should first read n,q and then declare a[n],m[q] like this:
int n, q;
scanf("%d %d", &n, &q);
int a[n];
int m[q];
I tried running your code giving 6 6 for the first scanf so n=6,q=6
and after that as your example i gave input:
1 2 3 4 5 6
0
1
2
3
4
5
and it printed right.
Don't use scanf. scanf is notoriously hard to use, and it's particularly wrong for your situation because it will not distinguish between different types of whitespace (spaces versus newlines).
Instead, you should read input line-by-line using fgets and then parse each line using sscanf or strtok.

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];
}
}

Parsing data from ASCII formatted file in C

I am trying to do what's been done here Read co-ordinates from a txt files using C Program . The data that I am trying to input is in this format:
f 10 20 21
f 8 15 11
. . . .
f 11 12 25
The only difference in my point structure is that I have a an extra char to store the letter in the first column (which may or may not be the letter f). I guess im either declaring my char wrong, or I'm calling it in printf incorrectly. Either way, I only get the first line read and then my program terminates. Any ideas ?
Here is my MWE below
#define FILEPATHtri "/pathto/grid1DT.txt"
#define FILEPATHorg "/pathto/grid1.txt"
#define MAX 4000
#include <stdio.h>
#include <stdlib.h>
#include "math.h"
typedef struct
{
float x;
float y;
float z;
char t[1];
}Point;
int main(void) {
Point *points = malloc( MAX * sizeof (Point) ) ;
FILE *fp ;
fp = fopen( FILEPATHtri,"r");
int i = 0;
while(fscanf(fp, "%s %f %f %f ", points[i].t, &points[i].x, &points[i].y, &points[i].z ) == 4 )
{
i++;
}
fclose(fp);
int n;
for (n=0; n<=i; n++){
printf("%c %2.5f %2.5f %2.5f \n", points[i].t, points[n].x, points[n].y, points[n].z ); }
printf("There are i = %i points in the file \n And I have read n = %i points ",i,n);
return 0;
}
Since there's only 1 char in there, not a string just use a single char in your code:
char t;
}Point;
Then when you read it in:
while(fscanf(fp, "%c %f %f %f ", &points[i].t, &points[i].x, &points[i].y, &points[i].z ) == 4 )
{
I'll note that having an array of 1 char, at the end of a structure, sets you up for the struct hack which might not have been your intentions... A good reason to use just char t instead of char t[1]
Also this line:
for (n=0; n<=i; n++){
Should be
for (n=0; n<i; n++){
One last note... if you wanted to print the character out that you read in the prints at the bottom, you should be using n:
// note your previous code was points[i].t
printf("%c %f %f %f \n", points[n].t, points[n].x, points[n].y, points[n].z ); }
Check this
while(fscanf(fp, "%c %f %f %f ", points[i].t, &points[i].x, &points[i].y, &points[i].z ) == 4 )
{
i++;
}
fclose(fp);
int n;
for (n=0; n<i; n++){
printf("%c %2.5f %2.5f %2.5f \n", points[n].t, points[n].x, points[n].y, points[n].z ); }
printf("There are i = %i points in the file \n And I have read n = %i points ",i,n);
getch();
return 0;
}
modification are since only a single character is read %s modified to %c also in printf its not points[i].t its points[n].t . Also the limit checking in for loop is also corrected to n<i

Resources