fscanf not reading/recognizing float numbers? - c

I'm trying to read from a file that has the format:
ID: x y z ...... other crap
The first line looks like this:
0: 0.82 1.4133 1.89 0.255 0.1563 armTexture.jpg 0.340 0.241 0.01389
I only need the x y z float numbers, the rest of the line is garbage.
My code currently looks like this:
int i;
char buffer[2];
float x, y, z;
FILE* vertFile = fopen(fileName, "r"); //open file
fscanf(vertFile, "%i", &i); //skips the ID number
fscanf(vertFile, "%[^f]", buffer); //skip anything that is not a float (skips the : and white space before xyz)
//get vert data
vert vertice = { 0, 0, 0 };
fscanf(vertFile, "%f", &x);
fscanf(vertFile, "%f", &y);
fscanf(vertFile, "%f", &z);
fclose(vertFile);
It's been changed a little for debugging (originally the first two scanfs used * to ignore the input).
When I run this, x, y, z do not change. If I make it
int result = fscanf(vertFile, "%f", &x);
result is 0, which I believe tells me it isn't recognizing the numbers as floats at all? I tried switching xyz to doubles and using %lf as well, but that didn't work either.
What could I be doing wrong?

%[^f] doesn't skip non-floats, it skips anything that's not the letter 'f'.
Try %*d: instead. * discards the number read, and a literal : tells it to skip over the colon. You can also combine all those individual reads.
fscanf(vertFile, "%*d: %f %f %f", &x, &y, &z);

Related

where I made the mistake and how to fix it?

#include <stdio.h>
float result(int x, int y);
float result1(int x, int y);
int main()
{
int x,y;
char z;
printf("enter x:\n");
scanf("%d",&x);
printf("enter y:\n");
scanf("%d",&y);
printf("enter z:\n");
scanf("%s",&z);
if (z=='*')
{printf("the result is %.2f",result(x,y));}
else if (z=='/')
{printf("the result is %.2f",result1(x,y));}
else
{printf("there is an error");}
return 0;
}
float result(int x, int y)
{
float r=x*y;
return r;
}
float result1(int x, int y)
{
float r1=x/y;
return r1;
}
```so this is my code. my out put is ---
enter x:
4
enter y:
5
enter z:
*
the result is 0.00
Question was -
take two integer number from user x and y and a character z. the result should be in float.
if z is * then it should be x*y
if z is / then it should be x/y
if z is none of the above then it will return 0
you need to use function .
so it was the question, I know it can be done by switch case but I wanted to try if else.
The problem is this:
scanf("%s",&z);
The format specifier %s is used to read null-terminated strings. The variable z is a single character, it can only hold the empty string (which is only the null-terminator and nothing else).
Any other input will write somewhere in memory and lead to undefined behavior.
If you want to read a single character use the format %c. But be careful, the newline that the Enter key added from previous input will also be read with %c, and you need to ask scanf to skip and ignore it. This is done by adding a leading space to the format string.
So the call should be:
scanf(" %c",&z);

Complex numbers through scanf in C

I have problem with following fragment of code:
int main()
{
int n = 3;
complex_t t[3];
for(int i = 0; i < n; i++)
{
double x, y;
printf("Enter complex number: ");
scanf("%f %f", &x, &y);
t[i].re = x;
t[i].im = y;
}
}
When I am trying to pass x, and y to the program, it doesn't change value, and is 0.00000.
Can you help me?
You've declared x and y as doubles, but then went on to use the format specifier for floats (%f). So the end result is reading them in as if they were regular floats, then jamming the result into a double leaving you with unexpected values when trying to actually use them.
You need to use the format specifier specifically for doubles (%lf) here.
scanf("%lf %lf", &x, &y);
See format string specifications for more information about different format specifiers.

Reading Scientific Notation in C

I am trying to read a file that has the following contents:
1.0000000e+01 2.9265380e+03 5.0821200e+02 4.3231640e+01
2.0000000e+01 1.0170240e+04 9.2798610e+02 4.0723180e+01
3.0000000e+01 2.1486260e+04 1.1832420e+03 1.0328000e+01
4.0000000e+01 3.3835080e+04 1.1882285e+03 -9.3307000e+00
5.0000000e+01 4.5250830e+04 1.0899705e+03 -1.0320900e+01
6.0000000e+01 5.5634490e+04 9.8935650e+02 -9.8019000e+00
7.0000000e+01 6.5037960e+04 8.9134700e+02 -9.8000000e+00
but I can't seem to find a proper way to read the scientific notation. Here is what I have of the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This is the array to store the input
double time[24], altitude[24], velocity[24], acceleration[24];
double var1, var2, var3, var4;
//This is the pointer declaration for opening a file
FILE * fp = fopen("rocket.txt", "r");
int i = 0;
while(fscanf(fp,"%g %f %f %f", &var1, &var2, &var3, &var4) > 0){
time[i] = var1;
altitude[i] = var2;
velocity[i] = var3;
acceleration[i] = var4;
printf("Time: %f \n", &time[i]);
i++;
}
printf("Time: %f", &time[0]);
fclose(fp);
return(0);
}
I've tried multiple combinations of %f, %g, %d to try and print out the result but I can never get the right thing.
If anyone can point me on the right direction I will greatly appreciate it.
What you want to use is %lf for input and %e for output in scientific notation:
scanf("%lf", &input);
printf("%e\n", input);
You could use a, e, f, or g in the conversion specifier like this:
fscanf(fp, "%a", &input); // NOTE: only with C99 compilers
fscanf(fp, "%e", &input);
fscanf(fp, "%f", &input);
fscanf(fp, "%g", &input);
They will all work for parsing floats, but for doubles you will need to use the length modifier "l" like this:
fscanf(fp, "%le", &input);
To print the values, you can use any of the specifiers but you don't need the length modifier "l":
printf("%e ", input); // or f or g (or a C99 compilers only)
printf("%le ", input); // produces the same thing
A really helpful reference is here:
http://en.cppreference.com/w/c/io/fscanf

C sscanf behaviour

I am trying to understand sscanf behaviour for that I have executed below two program.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
output is
x is 255, y is 11
Below program is not working as per my expectation.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d5.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
I am expecting 25,11, but the output is
x is 255, y is 0
I am expecting sscanf behaviour should exact same as sprintf in reverse manner. But its not working in my second program. If the format specifed is %d5.3%d, then it has to consider 5 as delimeter. But its not considering and reading all digits for x, and then dot is not matching with 5.3%d so it quits there.
Can somebody please explain this.
That's because the %d conversion specifier means sscanf will keep reading from the buffer pointed to by a till it encounters a non-numeric character in the buffer. This means that %d will consume up till 225 in the string literal "225.311" in your second example.
If the format specifed is %d5.3%d, then it has to consider 5 as
delimeter.
No, that's not true. 5 in the format string means sscanf will match it exactly (after reading an int) in the buffer it reads from. If it fails to match it, then sscanf will return and the value of y is left unchanged. You can check for this by storing the result of sscanf. The return value is equal to the number of input items successfully matched and assigned.
char *a = "225.311";
int x = 0, y = 0;
int retval = sscanf(a, "%d5.3%d", &x, &y);
printf("%d\n", retval); // prints 1
However, note that if the sequence of numeric characters in the buffer is too long to fit into an int, then the behaviour is undefined because of signed integer overflow.
Suggest using a different format and checking the results of sscanf(). Also to distinguish fractions like "0.001" and "0.1", note positions.
const char *a = "225.0311";
int ipart = 0;
unsigned fractionpart;
int n1, n2;
if (sscanf(a, "%d.%n%u%n", &ipart, &n1, &fractionpart, &n2) != 2) {
Handle_BadInput();
}
printf("ipart is %d, fractionpart is %0*u\n", ipart, n2 - n1, fractionpart);
// ipart is 225, fractionpart is 0311
As #ajay discusses, "%d5.3%d" looks for an int, then "5.3" then another int.

sscanf reads string in ( )

this question bothers me this few days.
I want to read a string for example, input = (-0.001999,-0.919191,-0.777777,999999.999999)
using sscanf. And my code is
char x[10], y[10], z[10], angle[10];
sscanf( input+1, "%[^,],%[^,],%[^,],%[^)]", &x, %y, &z, &angle);
printf("%s %s %s %s\n", x, y, z, angle);
the expected result is x=-0.001999 y=-0.919191 z=-0.777777 a=999999.999999
but my printf shows : x=-0.001999 y=-0.919191 z=999 a=999999.999999
can somebody help me figure out where the problem is ??
thx!
angle is not big enough to hold the input data and thus z is getting overwritten. Try this:
char x[80], y[80], z[80], angle[80];
After fixing the odd buffer overflow and such, I get:
char input[] = "(-0.001999,-0.919191,-0.777777,999999.999999)";
char x[10], y[10], z[10], angle[14];
sscanf( input+1, "%9[^,],%9[^,],%9[^,],%13[^)]", x, y, z, angle);
printf("%s %s %s %s\n", x, y, z, angle);
and the output I get from this is:
-0.001999 -0.919191 -0.777777 999999.999999
Your sscanf like should be sscanf( input+1, "%[^,],%[^,],%[^,],%[^)]", x, y, z, angle); since your arrays are already pointers (and the y has a % in your example). The other responder has solved the root problem.

Resources