All - This is NOT for a class assignment. I have written some C code to read a file of orbital information from a Russian site. I have figured out how to get it to read the first line only :-( of about 2800 lines. Sigh. I have looked at several books and some web sites.
Can anyone help me get a While loop working? So far it reads in the first of the lines, about 16 columns separated by commas. I have tried about a hundred variations of how to recognize the end of the file. Apparently the feof function is needed but I read in about 17 quantities from each line and cannot get the code to go past line 1. Grrr.
The code reads from an input file and creates and writes to an output file. I read into a structure.
I could provide code of course. This is vanilla C code on a Unix (Macintosh) box.
//
// OrbitManager.c
// copyright Charles Phillips
// 2018 may 12 cut out function to read from keyboard and printing
//
// this is the one that reads ISON orbits from a file and puts out to a file
#include <stdio.h>
#include <string.h> // strtok, strcpy stuff not even used yet
#include <stdlib.h> // atoi, atof not used yet
#include <math.h> // math functions
#define MU 398600.4418 // gravitational parameter
#define min_per_day 1440 // minutes per day
#define sec_per_day 86400 //seconds per day
#define PI 3.141592653589
#define Two_Pi 6.28 // 2 times Pi (for use in finding semi-major axis)
typedefstruct Satellite // set up structure to accept parameters
{
int sequence_number; // sequential number in their system - not needed?
int number; // ISON number
float first_seen; // date it was first seen
// char international_designator[12]; // not currently used
double epoch; // epoch time
float epoch_minutes; // darn them they have a space in epoch
int gap; // gap in days between something and something else
float semi_major; // semi major axis column 5
float inclination; // column 6
float RAAN; // column 7
float eccentricity; // column 8
float argument_latitude; // ISON has this number column 9
float argument_perigee; // column 10
float magnitude; // not needed column 11
float uncertainty; // not needed
int blah1; // some number, not needed
int blah2; // some number, not needed
int blah3; // some other not needed number
float apogee; // calculated later
float perigee; // calculated later
}Satellite;
// none of those are initialized with values, it is just the structure
// functions:
void readFile (Satellite *sat); // read information from keyboard
void inputFile (FILE* input, Satellite *sat1); // read from file
void printParameters (FILE* output, Satellite *sat1); // print to display, file
void calculateApogeePerigee (Satellite *sat1); // find apogee, perigee
int main(void)
{
char answer = 'x'; // this is the answer to the first while loop
Satellite sat1; // start a Structure called sat - need sat1, sat2,...sat(n)
// or are the fields numbered? indexed?
// increment sat number and then refer to the right number in every later line
FILE* input; // input points to file to read from
FILE* output; // output points to file to write to
// these next two lines are specific to my directories - a user will have to change them!!
input = fopen("/Users/Charles/Documents/1_OrbitManager_data/ison_data.txt", "r"); // read data from right place
output = fopen("/Users/Charles/Documents/1_OrbitManager_data/satellite_data.txt", "w"); // put satellite in right place
while (answer != 'q') {
printf("\nWhat do you want to do? Enter the letter for your response.\n\n");
printf(" c) Enter orbital information\n");
printf(" q) Quit\n\n");
scanf(" %c", &answer); // get answer from keyboard
switch (answer) {
case'c':
printf("I will take input from a file\n");
inputFile (input, &sat1);
// later add international designator as well
// need error check - did open input??
printf("now call calculate apogee and perigee\n"); // debug step, this does not show up
calculateApogeePerigee (&sat1);
printf("\nfor test, immediately print what was just input\n\n");
// printParameters (output, &sat1);
printf("I got the values and you can choose another option\n");
break;
case'q':
printf("You said to quit so I will quit\n");
break;
default:
printf("Invalid selection. Try again.\n");
break;
}
}
fclose(output); // close file we put output into
fclose(input); // close file we get input from
return 0;
}
void inputFile (FILE* input, Satellite *sat1) // read from input file
{
// put the check back here to see if input is there
printf("While loop is next"); // never gets here
// used to have each fscanf separately and that worked
while ( fscanf(input, "%d,%d,%f,%lf,%f,%d,%f,%f,%f,%f,%f,%f,%f,%f,%d,%d,%d",&sat1->sequence_number,&sat1->number,&sat1->first_seen,&sat1->epoch,&sat1->epoch_minutes,&sat1->gap,&sat1->semi_major,&sat1->inclination,&sat1->RAAN,&sat1->eccentricity,&sat1->argument_latitude,&sat1->argument_perigee,&sat1->magnitude,&sat1->uncertainty,&sat1->blah1,&sat1->blah2,&sat1->blah3) !=EOF)
{
// fscanf(input, "%f", &sat1->mean_anomaly); ISON does not supply this
// fscanf(input, "%f", &sat1->mean_motion); ISON does not supply this
calculateApogeePerigee (sat1); // why not &sat1?
} }
void calculateApogeePerigee (Satellite *sat1) // calculate apogee, perigee
{
// sat number will have to be fixed
float a; // a is semi-major axis, the formula didn't like the reference
a=sat1->semi_major;
sat1->apogee = (a * (1 + sat1->eccentricity)) - 6378.135;
sat1->perigee = (a * (1 - sat1->eccentricity)) - 6378.135;
}
One problem is that sat1 is a pointer so you don't need the & in front.
Try this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
void inputFile (FILE* input, Satellite *sat1) // read from input file
{
printf("While loop is next"); // never gets here
// used to have each fscanf separately and that worked
while ( fscanf(input, "%d,%d,%f,%lf,%f,%d,%f,%f,%f,%f,%f,%f,%f,%f,%d,%d,
%d",sat1->sequence_number,
sat1->number,sat1->first_seen,sat1->epoch,
sat1->epoch_minutes,sat1->gap,sat1->semi_major,sat1->inclination,
sat1->RAAN,
sat1->eccentricity,sat1->argument_latitude,sat1->argument_perigee,
sat1->magnitude,sat1->uncertainty,sat1->blah1,sat1->blah2,sat1->blah3) == 17)
{
/* maybe print some data to see if read correctly, maybe with a small test file first */
calculateApogeePerigee (sat1); // why not &sat1?
}
}
Sorry for the poor formatting. Just have a little tablet at the moment. :(
I will try it, but the &sat1 etc worked before. Now it seems that the code never gets to the while loop at all. I used to NOT have while in there, just did fscanf for each quantity.
You have 17 format specifier in your fscanf. == 17 means 17 fields read.
BTW Didn't you mention you want to read 16 somewhere else?
Anyway please show us some lines of the input so we can run it and see better where the problem is.
Thomas - 16 columns but one has a space in it and I couldn't figure out how to handle it, so I read it as another column. When I get to it I'll find a better solution. As you can see I try to solve one problem at a time.
> One problem is that sat1 is a pointer so you don't need the & in front.
`sat1' is a pointer
`sat1->sequence_number' is an integer
the scanf family expects pointers to the arguments, so you do need to write &sat1->sequence_number
the compler should have warned you about the mistake.
> Is this too long???
yes, it is.
your problem is with reading a file, your code has a menu and a function `calculateApogeePerigee()' that are irrelevant to the issue (or that they may be the issue while we focus on the other part)
strip your code to the bones.
> printf("While loop is next"); // never gets here
¿so you never pass the menu part?
get a debugger, run step by step and watch the variables
> 16 columns but one has a space in it and I couldn't figure out how to handle it
¿is the space always there?
then instead of %f,%fwrite %f %f
if not, you'll have to figure out what does that mean.
I see that you have some `-' in the columns (perhaps missing values)
maybe you should read always as string and then trying to convert to number
see atoi(), atof()
ne555 - I took the menu selection out so that I could paste the important code here, that also messed up my indentation some. This entire code is too long and this site refuses to let me put it all in. I also took out a big function to print the satellite information, input from the keyboard, etc. All of that works just fine.
The code runs the menu but does not get to the function to read the "input" file. The code does not seem to get to that printf you mentioned. I have a version of this code, very similar, that does successfully read the first line of a test input file.
I need to read the input file and then add some things like apogee, perigee, mean motion - etc. These are parameters that each satellite has but that the ISON file assumes that you will calculate them yourself from the included parameters.
I'll try that %f %f to try to read that one column with the space - I just had not gotten to that yet. And yes the input file has some dashes and I will get around to them.
I use XCode which is a very capable IDE but I thought that my problem was that the books talk about EOF and feof and I thought that I needed to put in what was the actual end of file marker.
I guess I could just make sure the file had a blank line at the end and search for a blank line?
I had a closer look at your code and would recommend a different approach.
Since you don't want all the data it would be easier to read it into a string first and read only the columns you need.
Thomas1965 - that looks like a good solution, so your function at line 65 reads the columns that I need.
Doesn't this task - read a file until the end - seem like a very very basic task? I thought that I was just using feof and EOF wrong and that I would get like 18 replies that told me how to do it. I still plan to figure that out. The books that I have read just don't show how this works.
Sorry I should have mentioned it. The books has nothing to do with windows.
The code examples are general and should work on Unix or Mac.
The author worked(works?) for Microsoft but also worked on the Office for Mac projects.