sscanf not scanning in the elements from string properly - c

I have created the following program
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const double PI = 3.14159;
int main()
{
char str[120];
double distance, azimuth;
double delta_x = 0;
double delta_y = 0;
FILE *fp = fopen("input.txt", "r");
if (fp == NULL)
return -1;
fgets(str, sizeof(str), fp); //skip first line
while (fgets(str, sizeof(str), fp)) {
if (strcmp("Dig here!", str) == 0)
break;
printf(str);
sscanf(str, "go %f feet by azimuth %f\n", &distance, &azimuth);
printf("distance %f azimuth %f\n", distance, azimuth);
delta_y += distance * sin(azimuth * (PI/180));
delta_x += distance * cos(azimuth * (PI/180));
}
printf("%d %d", delta_x, delta_y);
fclose(fp);
return 0;
}
input.txt looks something like this
Stand at the pole with the plaque START
go 500 feet by azimuth 296
go 460 feet by azimuth 11
Dig here!
However the output gives
go 500 feet by azimuth 296
distance 0.000000 azimuth 0.000000
I'm sure it's a dumb error I am missing but I can't seem to find it, any help would be appreciated.

The "%f" format specifier of scanf is for float type:
f – Matches an optionally signed floating-point number; the next pointer must be a pointer to float.
If you wish to parse a double type then use the l format specifier in combination with f:
l – Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long int or unsigned long int (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to double (rather than float).
So, you should change your format string as follows:
sscanf(str, "go %lf feet by azimuth %lf\n", &distance, &azimuth);
printf("distance %lf azimuth %lf\n", distance, azimuth);
Note that fgets may contain trailing '\n', in other words if a newline is read, it is stored into the buffer. Therefore before you compare the input coming from fgets against "Dig here!", you have to remove the newline first.
There is many options to do this, in the comments below you can see a good one or you can use the following approach with strcspn function:
str[strcspn(str, "\r\n")] = '\0'; /* works for any combination of CR and LF */
if(strcmp("Dig here!", str) == 0)
break;

Related

fscanf not reading/recognizing float numbers?

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);

How to print variables in a structure?

#include <stdio.h>
#include <math.h>
#define G 9.81
typedef struct
{
double weight;
double drag;
double time;
} USER_INPUT;
double calculateVelocity(USER_INPUT);
int main(int argc, char **argv)
{
USER_INPUT userInput;
double velocity;
printf("Please enter weight, drag and time: ");
scanf("%lf %lf %lf", &userInput.weight, &userInput.drag, &userInput.time);
velocity = calculateVelocity(userInput);
printf("At t = %f , the parachutist with weight %d kg\nand a drag coefficient %8.2f kg/s \n will have a velocity of %8.2f m/s^2", &userInput.time, &userInput.weight, &userInput.drag, velocity);
return 0;
}
double calculateVelocity(USER_INPUT data)
{
double velocity;
// TODO compute velocity
return velocity;
}
In the main function, I want to display the result.
How can I print variables defined in the structure?
I tried %f, which returns 0.000000, and %d returns a random number.
You are doing mistake while printing,
Please note '&' is used to get the address of any variable, not the value.So when you are printing:
printf("At t = %f , the parachutist with weight %d kg\nand a drag coefficient %8.2f kg/s \n will have a velocity of %8.2f m/s^2", &userInput.time, &userInput.weight, &userInput.drag, velocity);
you are actually printing the adderss of variables:
&userInput.time (address of (userInput.time)),
&userInput.weight(address of (userInput.weight)), &userInput.drag (address of (userInput.drag)).
You want to print their values, not address, hence remove '&' while printing:
ie;
printf("At t = %f , the parachutist with weight %d kg\nand a drag coefficient %8.2f kg/s \n will have a velocity of %8.2f m/s^2", userInput.time, userInput.weight, userInput.drag, velocity);
Well not sure about all the physics or which equation so I kind of faked that, but I got your program to compile and run so it should be pretty easy for you to fix it from here. Feel free to ask questions about the pointer stuff and why addresses were and weren't used in different places.
#include <stdio.h>
#include <math.h>
#define G 9.81
#define P 1.00 // ?
#define A 1.00 // ?
typedef struct {
double weight;
double drag;
double time;
} userInput_t;
double calculateVelocity(userInput_t *); // Terminal velocity?
double calculateVelocity(userInput_t *data) {
return sqrt((2 * data->weight * G)/(P * A * data->drag));
}
int main(void) {
userInput_t userInput;
printf("Please enter weight, drag and time: ");
scanf("%lf %lf %lf", &userInput.weight, &userInput.drag, &userInput.time);
double velocity = calculateVelocity(&userInput);
printf("\nAt t = %f, the parachutist with weight %f kg\n"
"and a drag coefficient %f kg/s\n"
"will have a velocity of %f m/s^2\n",
userInput.time, userInput.weight, userInput.drag, velocity);
}
int printf(const char *format, ...);
is NOT
int scanf(const char *format, ...);
scanf works with memory addresses of variables, while printf with variables itselves.
It's UB trying to
printf ("%d", memory_addres_of_variable);
because the right way to print memory addresses is with %zu starting from C99 and later, and %lu with ANSI C 90.
That's why you aree seeing a random number.
The issue is not related to struct. You are passing addresses of variables instead of their values to printf. So the solution is simple: Remove the & before variable names in the printf call.
This is a common mistake: scanf needs the addresses of variables to be able to alter their values, while printf just takes the values. Unfortunately even the prototypes do not make it evident:
int printf(const char *format, ...);
int scanf(const char *format, ...);
And you need to use %f for double variables (derived from the type called float), %d is used for int (decimal).
The result:
printf("At t = %f , the parachutist with weight %f kg\nand a drag coefficient %8.2f kg/s \n will have a velocity of %8.2f m/s^2", userInput.time, userInput.weight, userInput.drag, velocity);
References:
http://en.cppreference.com/w/cpp/io/c/fprintf
http://en.cppreference.com/w/c/io/fscanf

Squared Equation calculator not working in C

Hello guys I started learning C few weeks ago and I am trying to make my first useful program, I am trying to create a squared equation calculator but no matter what I type in the input it always outputs "no solution2" can anyone take a look and help me ?
examples for input :
0 0 0=
1 4 1=
#include <stdio.h>
#include <math.h>
int main()
{
printf("enter a\n");
double a; scanf("%1f", &a);
printf("\nenter b\n");
double b; scanf("%1f", &b);
printf("\nenter c\n");
double c; scanf("%1f", &c);
if (a==0)
{
if (b==0)
{
if (c==0)
printf("x can be every number\n");
else
printf("no solution1\n");
}
else
{
printf("x equals %.2f\n", ((-1)*c) / b);
}
}
else
{
double delta = (b*b)-(4*(a*c));
if (delta>0)
{
double sqrtDlt = sqrt(delta);
printf("x1 = %4.2f\n", (((-1)*b) + sqrtDlt) / 2 * a);
printf("x2 = %4.2f\n", (((-1)*b) - sqrtDlt) / 2 * a);
}
else
printf("no solution2\n");
}
return 0;
}
For double use specifier %l(ell)f not %1(one)f in scanf.
Note that this is one place that printf format strings differ substantially from scanf (and fscanf, etc.) format strings. For output, you're passing a value, which will be promoted from float to double when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf whether you want to read a float or a double, so for scanf, %f means you want to read a float and %lf means you want to read a double.

input a float with two digits of precision

I am working on a problem that requires me to input a float with exactly 2 digits of precision.
I know how to print a float with two digits of precision but how can I input a float under this condition? I think this is the problem with my program because there is no compilation error as such but it just says wrong answer. I am working with C language.
I tried to read an int and a float with two digits of precision as required the following way:
int x;
float balance,y;
scanf("%d %.2f",&x,&y);
For complete references, here are the question and my solution
There is a problem in proposed solution. According to cplusplus.com, the format f only accepts a width and no precision.
If you had controlled the return from the scanf (what you should definitively always do - and now you know why !) you would have seen immediately the problem :
int x, cr;
float balance,y;
cr = scanf("%d %.2f",&x,&y);
if (cr != 2) {
fprintf(stderr, "Read error : cr = %d\n", cr);
}
Given any input, you will get :
Read error : cr = 1
Possible implementation with very little change :
cr = scanf("%d %f",&x,&y);
if (cr != 2) {
fprintf(stderr, "Read error : cr = %d\n", cr);
}
// should round to only two digits - within floating point accuracy
y = (((double)((int)(y * 100 + 0.5))) / 100.);
If you have a system where math.h contains round (not MSVC :-( ), last line is better written as (thanks to chux for proposing it) :
y = round(y * 100)/100
because above formula will fail for negative y and for y > INT_MAX / 100
If you really needed exact precision with two decimal digit, the correct way would be to do all computation as integer on long, taking the numbers multiplied by 100. I leave that as an exercise for the reader :-)
This answer inputs a float then checks it was in the correct format. But If you are working with money you should be using int cents; unless you have megabucks and don't care about cents, or are working to fractions of a penny (in which case you could work in 10th of a penny).
#include <stdio.h>
#include <string.h>
#define BUFLEN 20
int main()
{
float money;
char buff[BUFLEN+1], bank[BUFLEN+1], *eptr;
printf ("Input the money: ");
if (fgets(buff, BUFLEN, stdin) == NULL) {
printf("Failed input\n");
return 1;
}
if ((eptr = strchr (buff, '\n')) != NULL) // newline?
*eptr = 0; // terminate
if (sscanf(buff, "%f", &money) != 1) { // get the money
printf("Failed input\n");
return 1;
}
sprintf(bank, "%0.2f", money); // check format of entry
if (strcmp(bank, buff)) {
printf("2 digit precision please: Euros.cents\n");
return 1;
}
printf("You paid %s\n", bank);
return 0;
}

(C) Reading from a Text File to a Structure

I am trying to read multiple different data types (char, int, float) from a text file directly into a Structure.
readData() {
char filename[100];
int linesread;
int i = 0;
printf("Enter the assets text file that you wish to read: \n");
scanf("%s", filename);
if ((fp = fopen(filename, "r")) == NULL) {
printf("Error opening data file\n");
readData();
} else {
while (fscanf(fp, "%s %c %s %lf %lf %d %d %d", &assets[i].name, &assets[i].type, &assets[i].location, &assets[i].longi, &assets[i].lati, &assets[i].speed, &assets[i].fuelTime, &assets[i].readyTime != EOF)) {
i++;
}
}
fclose(fp);
linesread = i;
for (i = 0; i < linesread; i++) {
printf("%s %s %s %lf %lf %d %d %d\n", &assets[i].name, &assets[i].type, &assets[i].location, &assets[i].longi, &assets[i].lati, &assets[i].speed, &assets[i].fuelTime, &assets[i].readyTime);
}
This Should read this out (when it decides to co-operate) and save it into the structure:
Angle_Lifeboat L Angle 51.685 -5.102 25.0 600 120
Angle_ILB L Angle 51.685 -5.102 25.0 180 30
Broad_Haven_ILB L Broad_Haven 51.713 -5.113 25.0 180 30
But instead reads this
ngle_Lifeboat LAngle Angle 0.000000 0.000000 0.000000 4231936 4231940
Angle_ILB LAngle Angle 0.000000 0.000000 0.000000 4232008 4232012
Broad_Haven_ILB LBroad_Haven Broad_Haven 0.000000 0.000000 0.000000 4232080 4232084
I am pretty new to C, so go easy on me. Any help you can give would be massively appreciated
EDIT: Stucture -->
typedef struct assets{
char name[25];
char type[1];
float longi;
float lati;
char location[20];
int speed;
int fuelTime;
int readyTime;
} assets;
In c programming i do think there is already an in build function to do the above ...
try using fread http://www.tutorialspoint.com/c_standard_library/c_function_fread.htm
fread(&my_struct, sizeof(my_struct), 1, fp);
BLUEPIXY correctly noticed the != EOF bad position; correct is:
… &assets[i].readyTime) != EOF) {
We cannot print the character in assets[i].type as a string with %s, because that 1-char-array type[1] doesn't have (room for) the terminating null character; we must print it as a string with precision .1 or a character:
printf("…%.1s…\n", …assets[i].type…); // need no & operator
or
printf("…%c…\n", …*assets[i].type…); // need * operator
The conversion specification %lf is for a pointer to double (rather than float); the floats need the conversion specification %f.
Since the speed values are 25.0, we cannot read them as integers with %d; we rather need to read a float variable with %f, either a temporary variable which is then assigned to assets[i].speed, or by defining float speed; in assets.

Resources