So, I'm trying to get my program to read into an array of structs from a text file, and it compiles okay, but doesnt appear to actually be reading in the values?.. and I have no idea why. This is the relevant part of the code:
typedef struct Planet
{
char Planet_Name[30];
double Fuel;
double Velocity;
double Height;
double Gravity;
int Maximum_Thrust;
double Difficulty;
}Planet;
//read the Planets from a file
FILE* inputFile = fopen("Planets.txt", "r");
if(inputFile == NULL)
{
perror("Error. File unavailable");
exit(1);
}
for(j=0; j<10; j++)
{
fscanf("%29s %lf %lf %lf %lf %d %lf", SolarSystem[j].Planet_Name,
SolarSystem[j].Fuel, SolarSystem[j].Velocity,
SolarSystem[j].Height, SolarSystem[j].Gravity,
SolarSystem[j].Maximum_Thrust, SolarSystem[j].Difficulty);
}
printf("Please select a planet by entering the corresponding number:
Mercury[0], Venus[1], Earth[2], Moon[3], Mars[4], Jupiter[5], Saturn[6],
Uranus[7], Neptune[8]\n");
scanf("%d",&PlanetNum);
printf("You have chosen %s", SolarSystem[PlanetNum].Planet_Name);
This is the txt file (Title: Planets.txt)
Mercury 120 50 500 12.1 30 2
Venus 120 50 500 29.1 30 6
Earth 120 50 500 32.2 30 7
Moon 120 15 50 5.3 30 2
Mars 120 50 500 12.2 30 4
Jupiter 120 50 500 81.3 30 10
Saturn 120 50 500 34.3 30 8
Uranus 120 50 500 28.5 30 5
Neptune 120 50 500 36.6 30 9
Pluto 120 50 500 2.03 30 1
Except when it runs that final printf, it doesn't actually print anything, nor does it store any data in the structs (when its called later it's all zeroes).
Ideas?
The mistake is with your fscanf function . You have to provide FILE pointer (inputFile This context) as first argument and & operator(address of Similar to scanf function) in front of scanning integer and float.
Try this modified fscanf code :-
fscanf(inputFile,"%s%lf%lf%lf%lf%d%lf",SolarSystem[j].Planet_Name,&SolarSystem[j].Fuel, &SolarSystem[j].Velocity, &SolarSystem[j].Height, &SolarSystem[j].Gravity,&SolarSystem[j].Maximum_Thrust, &SolarSystem[j].Difficulty);
Related
In my C programming class we are supposed to write a program that is able to perform unit conversion. This is to be done by taking a filename and the desired conversion from the user, opening the file, identifying the conversion factors within the file, closing the file, and displaying the final conversion.
Here is the sample file lengths that the instructor provided:
INCH 0.0254
FOOT 0.3048
YARD 0.9144
MILE 1609.344
MM 1e-3
CM 1e-2
METER 1
KM 1e3
AU 149597870700.0
Here is sample output that we need to replicate exactly:
% c11 -Wall units.c -o u
% ./u lengths 12 inch foot
12.00 inch is 1.00 foot.
% ./u lengths 30 inch foot
30.00 inch is 2.50 foot.
% ./u lengths 1 foot inch
1.00 foot is 12.00 inch.
% ./u lengths 1 inch foot
1.00 inch is 0.08 foot.
% ./u lengths 1 au mile
1.00 au is 92955807.27 mile.
% ./u lengths 1000 meter km
1000.00 meter is 1.00 km.
% ./u lengths 1 inch mile
1.00 inch is 0.00 mile.
% ./u
usage: ./u <unitfile> <amount> <from> <to>
% ./u lengthz 1 inch foot
./u: can’t open file lengthz
% ./u lengths 1 inch feet
./u: no such unit "feet"
What libraries must I include in order to make this program work? What is the best way to take input from the user in this situation?
Update:
After a bit of trial and error, I was able to get my program to take the command line arguments. Here is what I have so far:
#include <stdio.h>
#include <stdlib.h>
// Function to take file name from the user input
int main(int argc, char* argv[])
{
if (argc != 5)
{
printf("usage: %s filename\n", argv[0]);
}
else
{
FILE *file = fopen(argv[1], "r");
if (file == 0)
{
printf("can't open file %s\n", argv[1]);
}
else
{
int x;
while ((x = fgetc(file)) != EOF)
{
printf("%c", x);
}
fclose(file);
}
}
}
Unfortunately, this only prints the contents of the file assuming that the program gets 5 command line arguments.
This question already has answers here:
What range of numbers can be represented in a 16-, 32- and 64-bit IEEE-754 systems?
(7 answers)
Closed 6 years ago.
I would like to output like "correct output data" from "input data" by below C program. But the result shows that the values are changed like "actual output data". Let me know how to solve it.
input data
-5190.978 -90026.901 158.677 15 90 81 58
-5165.821 -90011.875 152.742 15 90 89 54
-5158.762 -90010.093 148.083 31 80 82 42
correct output data
-5190.978 -90026.901 158.677 90 81 58
-5165.821 -90011.875 152.742 90 89 54
-5158.762 -90010.093 148.083 80 82 42
actual output data
-5190.978 -90026.898 158.677 90 81 58
-5165.821 -90011.875 152.742 90 89 54
-5158.762 -90010.094 148.083 80 82 42
/***************************************************************************:::
xyz(ref)rgb2xyzrgb
19/08/2016
ver1.1 2009/3/7
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(int argc,char *argv[])
{
FILE *fpr,*fpw;
int ref,r,g,b;
float x,y,z;
float n_x,n_y,n_z;
/*****************************************************
2.command line arguments processing
*******************************************************/
if(argc!=3)
{
fprintf(stderr,"Usage: %s (1)input_org.txt\n(2)write_xyz FILENAME\n",argv[0]);
exit(1);
}
printf("OPEN FILE NAME:%s\n",argv[1]);
/**********************************************************************************
**********************************************************************************
4. FILE OPEN + Binary File Input
**********************************************************************************
*************************************************************************************/
// open input file
if((fpr=fopen(argv[1],"rt"))==NULL)
{
printf("file cannot be opened。\n");
exit(1);
}
//write file
if((fpw=fopen(argv[2],"wt"))==NULL)
{
fprintf(stderr,"DSM by GSI data.raw\n");
exit(1);
}
while (fscanf(fpr,"%f %f %f %d %d %d %d", &x,&y,&z,&ref,&r,&g,&b) != EOF)
{
//printf("%.3f %.3f %.3f %d %d %d\n",x,y,z,r,g,b);
n_x = roundf(x * 1000) / 1000;
n_y = roundf(y * 1000) / 1000;
n_z = roundf(z * 1000) / 1000;
//printf("%.3f %.3f %.3f %d %d %d\n",n_x,n_y,n_z,r,g,b);
fprintf(fpw,"%.3f %.3f %.3f %d %d %d\n",n_x,n_y,n_z,r,g,b);
//printf("x:%f y:%f z:%f\n", x,y,z);
}
fclose(fpr);
fclose(fpw);
}
Instead of -90026.901 computer stores the nearest number that fits the precision. It's 90026.898. Remember that numbers are stored in binary on computers and 901/1000 doesn't have finite binary form. For this reason, some of the precision will be cut.
It would be the same if you tried to print 1/3. It won't print all the digits, but you actually expect it as you're used to decimal system. In binary system, some of the fractions that have finite decimal form won't have one.
The solution? Always try to enlarge macheps which is the arithmetic precision. The easiest would be to use double instead of float. It still doesn't give 100% but it's more probable that will work.
The topic is known as scientific calculation and is pain in a** for programmers.
#include<stdio.h>
main()
{
int Fahrenheit;
for (Fahrenheit = 0; Fahrenheit <= 300; Fahrenheit = Fahrenheit + 20)
printf("%3d %06.3f\n", Fahrenheit, (5.0/9.0)*(Fahrenheit-32));
}
Output of the source above:
0 -17.778
20 -6.667
40 04.444
60 15.556
80 26.667
100 37.778
120 48.889
140 60.000
160 71.111
180 82.222
200 93.333
220 104.444
240 115.556
260 126.667
280 137.778
300 148.889
Please explain to me the function of '06.3f' in the 'printf' function in the program above.
0 fill with 0 on the left
6 the string should be at least 6 characters long
.3 precision is 3 digits after the decimal point
f it accepts a float (or double) variable
I am in the early stages of coding a homework assignment. The larger goal is a little bit bigger and beyond the scope of this question. The immediate goal is to take one or more two digit numbers from the command line which correspond to years (e.g. 52). Then open the file that goes with that year. The files are formatted thusly:
1952 Topps baseball
-------------------
8 10 15 17 20 47 48 49 59 71 136
153 155 159 162 168 170 175 176 186 188 202
215 233 248 252 253 254 257 259 264 270 271 272 274
282 283 284 285 287 293 294 295 297 299 300 308 310 311
312
Each file has a random (between 1-50) number of 1-3 digit integers. I store the year in an int. Then I store each of the later digits into an array. Then I will use that array to do other cool stuff. My problem is, how to I scan for a random number of integer inputs from the file. THis is what I have done so far:
#include <stdio.h>
#include <string.h>
main(int argc, char** argv) {
char filename[30];
int cards[100];
FILE *fp;
int year,n,i;
for (i=1; i<argc; i++) {
n=atoi(argv[i]);
sprintf (filename,"topps.%d",n);
if (!(fp=fopen(filename,"r"))){
printf("cannot open %s for reading\n",filename);
exit(3);
}
fscanf (fp, "%d%*s%*s%*s%d%d%d%d%d%d%d%d%d%d%d%d",
&year,
&cards[i],
&cards[i+1],
&cards[i+2], //this is what needs to be improved upon
&cards[i+3],
&cards[i+4],
&cards[i+5],
&cards[i+6],
&cards[i+7],
&cards[i+8],
&cards[i+9],
&cards[i+10],
&cards[i+11],
&cards[i+12]);
printf ("%d\n",year);
printf ("%d\n",cards[i+11]);
}
}
The current fscanf is just a sort of stopgap to make sure I can read and print the info. It stores up to the 12th integer and prints it. For obvious reasons I didn't want to go to the 50th, because it's pointless. Some files only have 2 or 3 numbers in them. Can anyone help guide me to a more ideal solution for reading files like this? Thanks for having a look.
Something like this does the trick:
Declare 3 new variables at the top:
char sData[10000];
char * pch;
int j = 0;
Then replace your number reading code with the snippet below:
fscanf (fp, "%d%*s%*s%*s", &year);
/* ignore the line with all the dashes (crude, but works)*/
fgets(sData, 10000, fp);
/* read all the number data in */
fgets(sData, 10000, fp);
pch = strtok (sData," ");
j = 0;
while (pch != NULL)
{
cards[j++] = atoi(pch);
pch = strtok (NULL, " ");
}
At the end of this code, cards[] should have all your numbers, and j should contain the count.
I greatly appreciate the help I got from everyone. It definitely led me down the right path. However, this is the answer to the problem that eventually worked for me:
fscanf(fp,"%*[^\n]%*c"); //Skip first two
fscanf(fp,"%*[^\n]%*c"); //lines of file
while (!feof(fp)) { //Read ints into array
fscanf(fp,"%d ",&cards[i++]);
}
I'm having a hard time using sscanf to scan hour and minutes from a list. Below is a small snip of the list.
1704 86 2:30p 5:50p Daily
1711 17 10:40a 2:15p 5
1712 86 3:10p 6:30p 1
1731 48 6:25a 9:30a 156
1732 100 10:15a 1:30p Daily
1733 6 2:15p 3:39p Daily
I've tried this, but it keeps getting me segmentation Fault.(I'm putting this information into structures).
for(i=0;i<check_enter;i++){
sscanf(all_flights[i],
"%d %d %d:%d%c %d:%d%c %s",
&all_flights_divid[i].flight_number,
&all_flights_divid[i].route_id,
&all_flights_divid[i].departure_time_hour,
&all_flights_divid[i].departure_time_minute,
&all_flights_divid[i].departure_time_format,
&all_flights_divid[i].arrival_time_minute,
&all_flights_divid[i].arrival_time_minute,
&all_flights_divid[i].arrival_time_format,
&all_flights_divid[i].frequency);
printf("%d ",all_flights_divid[i].flight_number);
printf("%d ",all_flights_divid[i].route_id);
printf("%d ",all_flights_divid[i].departure_time_hour);
printf("%d ",all_flights_divid[i].departure_time_minute);
printf("%c ",all_flights_divid[i].departure_time_format);
printf("%d ",all_flights_divid[i].arrival_time_hour);
printf("%d ",all_flights_divid[i].arrival_time_minute);
printf("%c ",all_flights_divid[i].arrival_time_format);
printf("%s\n",all_flights_divid[i].frequency);
}
This is how I declared it.
struct all_flights{
int flight_number;
int route_id;
int departure_time_hour;
int departure_time_minute;
char departure_time_format;
int arrival_time_hour;
int arrival_time_minute;
char arrival_time_format;
char frequency[10];
};
struct all_flights all_flights_divid[3000];
These are the results I get
1704 86 2 30 p 0 50 p Daily
1711 17 10 40 a 0 15 p 5
1712 86 3 10 p 0 30 p 1
1731 48 6 25 a 0 30 a 156
1732 100 10 15 a 0 30 p Daily
1733 6 2 15 p 0 39 p Daily
Small mistake, that might be the problem:
this:
&all_flights_divid[1].flight_number,
should be:
&all_flights_divid[i].flight_number,
// ^
Edit:
Also, you read arrival_time_minute twice, and not reading arrival_time_hour at all. Fix it and it should be OK.
Most of the results seem to be fine, except the first field.
Now if you check your code..
&all_flights_divid[1]
fix it with
&all_flights_divid[i]