I have the following text file:
ax: 0
ay: -9.8
x: 0
y: 50
vx: 8.66
vy: 6
I want to read only the numerical values to be used for computations. Is there a way to ignore the strings and just read the values as floats?
Here is what I have so far:
FILE *fp;
FILE *fr;
fr = fopen("input_data", "rt");
fp = fopen("out_file.txt", "w");
if(fr == NULL) {
printf("File not found");
}
if(fp == NULL) {
printf("File not found");
}
float ax = 0, ay = 0,
x = 0, y = 0,
vx = 0, vy = 0,
time = 0, deltaTime = 0;
fscanf(fr, "%f %f %f %f %f %f %f %f\n",
&ax, &ay, &x, &y, &vx, &vy, &time, &deltaTime);
printf("%f %f %f %f %f %f %f %f\n",
ax, ay, x, y, vx, vy, time, deltaTime);
Use this instead:
fscanf(fr, "ax: %f ay: %f x: %f y: %f vx: %f vy: %f", &ax, &ay, &x, &y, &vx, &vy);
Use %s where the strings go.
Sample code :
#include <stdio.h>
main()
{
FILE *fp;
FILE *fr;
char junk[100];
fr = fopen("/tmp/x.txt", "rt");
if(fr == NULL){ printf("File not found");}
float ax = 0, ay = 0, x = 0, y = 0, vx = 0, vy = 0, time = 0, deltaTime = 0;
fscanf(fr, "%s %f %s %f %s %f %s %f %s %f %s %f\n", junk, &ax, junk, &ay, junk, &x, junk, &y, junk, &vx, junk, &vy);
printf("%f %f %f %f %f %f\n", ax, ay, x, y, vx, vy);
}
Related
Consider the following code:
#include <stdio.h>
#include <math.h>
#define INFTY 1000.0
#define EPS 0.0001
#define XRANGE 2
#define URANGE 2
float absf(float);
float E(float,float,float,float,float,float);
int main(){
FILE* out;
float T,R,G,ALPHA,STEP,x,u;
char filename [45];
int c;
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("Enter the dimensionless parameters greater or equal to 0:\nT = ");
scanf("%f",&T);
do { c=getchar(); } while ( c != '\n');//flush stdin
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("R = ");
scanf("%f",&R);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("G = ");
scanf("%f",&G);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("alpha = ");
scanf("%f",&ALPHA);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("step size (recommended:0.001 to 0.01): ");
scanf("&f",&STEP);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
if((T<0)||(R<0)||(G<0)||(ALPHA<0)||(STEP<0)) return 1;//crash if <0
sprintf(filename,"%.4g_%.4g_%.4g_%.4g_%.5g.dat",T,R,G,ALPHA,STEP);
out = fopen(filename,"w");
fprintf(out,"#T=%.3e R=%.3e G=%.3e alpha=%.3e\n",T,R,G,ALPHA);
//do the job
fclose(out);
return 0;
}
The issue here is that it seems to completely ignore the last scanf() where the step size is supposed to be entered; it just takes whatever junk was in the memory and goes with it, usually a very small number. This output is very characteristic:
0.000000 0.000000 0.000000 0.000000 72406190763540480.000000
Enter the dimensionless parameters greater or equal to 0:
T = 1
1.000000 0.000000 0.000000 0.000000 72406190763540480.000000
R = 1
1.000000 1.000000 0.000000 0.000000 72406190763540480.000000
G = 1
1.000000 1.000000 1.000000 0.000000 72406190763540480.000000
alpha = 1.2
1.000000 1.000000 1.000000 1.200000 72406190763540480.000000
step size (recommended:0.001 to 0.01): 0.01
1.000000 1.000000 1.000000 1.200000 72406190763540480.000000
As is evident, it's possible to overwrite every variable except the last one. The file is created even before the last scanf() is complete. Moving the step size input to the top produces another issue:
step size (recommended:0.001 to 0.01): 0.01
Enter the dimensionless parameters greater or equal to 0:
T = R = 1
G = 1
alpha = 1.2
^C
In this case, STEP wasn't actually overwritten by 0.01, but remained a very small number.
I have looked for similar cases, but there doesn't seem to be any widespread issues like rogue spaces in the input. I'm flushing stdin after scanf() as suggested here.
I'm looking forward to any advice. Thanks in advance.
You have used '&' in place of '%' in scanf("&f",&STEP);
#include <stdio.h>
#include <math.h>
#define INFTY 1000.0
#define EPS 0.0001
#define XRANGE 2
#define URANGE 2
float absf(float);
float E(float,float,float,float,float,float);
int main(){
FILE* out;
float T,R,G,ALPHA,STEP,x,u;
char filename [45];
int c;
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("Enter the dimensionless parameters greater or equal to 0:\nT = ");
scanf("%f",&T);
do { c=getchar(); } while ( c != '\n');//flush stdin
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("R = ");
scanf("%f",&R);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("G = ");
scanf("%f",&G);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("alpha = ");
scanf("%f",&ALPHA);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("step size (recommended:0.001 to 0.01): ");
Replace &f with %f, it will work in
scanf("&f",&STEP);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
if((T<0)||(R<0)||(G<0)||(ALPHA<0)||(STEP<0)) return 1;//crash if <0
sprintf(filename,"%.4g_%.4g_%.4g_%.4g_%.5g.dat",T,R,G,ALPHA,STEP);
out = fopen(filename,"w");
fprintf(out,"#T=%.3e R=%.3e G=%.3e alpha=%.3e\n",T,R,G,ALPHA);
//do the job
fclose(out);
return 0;
}
I'm getting an error:
Type invalid operands to binary & (have 'int *' and 'int')
here is my program. The problem occurs at line 34 or the fscanf num1
#include <stdio.h>
#include <stdlib.h>
FILE *infile;
FILE *prnt;
main()
{
int num1, num2, nums;
char complex;
float fcost;
char name [11];
infile = fopen ("F:/DATA.txt", "r");
prnt = fopen ("F:/income.txt", "w");
if (infile == 0)
{
printf ("FILE NOT ON DISK\n");
system("pause");
return 0;
}
fprintf (prnt, "%-15s %-23s %6s\n\n", "ABAHLMAN", "Program 1", "PAGE 1");
fprintf (prnt, "\n");
fscanf (infile, " %i %i %i %f %c", &nums &num1 &num2 &fcost &name);
while (!feof (infile))
{
int area = (nums * 200) + (num1 * 300) + (num2 * 450);
float cost = fcost + (area * 75.00);
double income = 12 * ((nums *450) + (num1 * 550) + (num2 *700));
float payback = cost/ income;
fprintf (prnt, "%-10s %5f %7c %9.2f\n", name, payback, area, cost);
fscanf (infile, " %d %d %d %f %c", &nums &num1 &num2 &fcost &name);
}
fclose (infile);
fclose (prnt);
return 0;
}
You are not separating the arguments with comma in fscanf() statements. They should be:
fscanf (infile, " %i %i %i %f %s", &nums, &num1, &num2, &fcost, name);
and
fscanf (infile, " %d %d %d %f %s", &nums, &num1, &num2, &fcost, name);
Note that name is an array and it gets converted into a pointer when you pass it to fscanf(). So, the & operator needs to be dropped. As noted in the comments, the format should be %c for name.
Also, see: What is array decaying?
I'd also suggest to use a standard definition for main() function. main() {..} is outdated and should be avoided.
Instead, you can write it as int main(int).
I see a few problems. First, no commas to separate the arguments for scanf.
Next, the last argument for fscanf should have %s format and be passed name without &.
Next, feof is not the way to control a loop, you should check the return value from fscanf anyway.
You also use the wrong format specifier %c for area in printf which should be %d
Finally be consisent with the use of %d or %i format specifier. Unless you want the user to input in other number bases than decimal, stick to %d.
So I suggest the loop should be
while (fscanf (infile, " %d %d %d %f %s", &nums, &num1, &num2, &fcost, name) == 5)
{
int area = nums * 200 + num1 * 300 + num2 * 450;
float cost = fcost + area * 75.00;
double income = 12 * (nums * 450 + num1 * 550 + num2 * 700);
float payback = cost / income;
fprintf (prnt, "%-10s %5f %7d %9.2f\n", name, payback, area, cost);
}
I am reading some .txt files that have data on it. My "strategy" for doing this is just reading the file line by line. I have no problems doing this task, however, at some point I have a string with different data (separated by spaces). I just want to read some data, because I do not need all the data. I used sscanf from string.h for doing this, this is an example of what I have:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "1 189.37823 62.18428 2.486 25.33 -21.73 -21.68 -22.01 10.12 10.13 10.11 10.08 9.95 9.89 9.91 7 8.7 0 -42.85";
int id, xid;
double z, r, d, sfr, tmp;
sscanf(str, "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&id, &z, &r, &d, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp,
&tmp, &sfr, &xid, &tmp);
printf("id = %d, z = %lf, r = %lf, d = %lf, sfr = %lf, xid = %d\n", id, z, r, d, sfr, xid);
}
However, my solution is quite inelegant, I am just "reading" all the data, and for the data I don't need I use a temporal variable. Is there a more correct (and perhaps more efficient) way for doing this?
Use %*f to read real value and drop it.
sscanf(str, "%d %lf %lf %lf %*f %*f %*f %*f %*f %*f %*f %*f %*f %*f %*f %*f %lf %lf %*f",
&id, &z, &r, &d, &sfr, &xid);
If we may, just ignore the last one, because it's not necessary,
then we have:
sscanf( str, "%d %lf %lf %lf, &id, &z, &r, &d);
for(int i = 0; i < 12; i++) // easy to control skip how many number
sscanf( str, "%lf, &tmp);
sscanf( str, "%lf %lf", &sfr, &xid);
Hi just getting some weird outputs from trying to read the inputs as double values in C. This issue does not occur when the inputs are integers is there anyway to make it work with double?
#include "stdafx.h"
int main(void)
{
double a, b, c, d, i;
FILE *inp;
inp = fopen("C:\\Users\\student\\Documents\\Visual Studio2012\\Projects\\ConsoleApplication3\\test.txt", "r");
i = fscanf(inp, "%f %f %f %f", &a, &b, &c, &d);
while (i != EOF)
{
printf("a = %f & %d \n", a, i);
printf("b = %f & %d \n", b, i);
printf("c = %f & %d \n", c, i);
printf("d = %f & %d \n", d, i);
printf("%d \n", EOF);
i = fscanf(inp, "%f %f %f %f", &a, &b, &c, &d);
}
fclose(inp);
return 0;
}
Figured it out, the %f in fscanf should be %lf
Change the specifier to %lf in fsacnf and printf statements. Like this -
fscanf(inp,"%lf %lf %lf %lf", &a, &b, &c, &d);
Other problems -
1.Also i is declared as double but in printf you print it with specifier %d ,so you pass wrong argument -
printf("a = %f & %d \n", a, i); // similar in all printf's
So according to me declare i as int and then print it.
2.Also you should always check return of fopen so check it.
int k;
float regionID;
int t;
char string[100];
float avgTemp,totalTemp;
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 %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, ®ionID);
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);
}
So, my program reads my file almost perfectly, but it will not read the first line of my file. Anyone know what might be causing this problem and how I might be able to fix it?
You are quite intentionally reading and discarding a line here:
if (fgets(string, sizeof(string), fp) == 0) {
I think you meant to use sscanf instead of fscanf, so that you use the data returned to you by fgets.
sscanf(string,"%d %f %d %d %d %d %d %f %f %f", ... );
The reason why your program is "not reading the first line of the file" is because it actually already read the first line when you called
if (fgets(string, sizeof(string), fp) == 0)
The change to fix this is simple:
for(k = 0; k < MAX_STATIONS; k++)
{
if (fscanf(fp,"%d %f %d %d %d %d %d %f %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,
®ionID) > 10)
{
break;
}
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);
}
Note the fscanf's return value:
On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.
Hope this is what you are looking for!