I am trying to use the harversine function after scannig the test file
stoptimes.txt
I have defined the macro STOPTIMES as
#define STOPTIMES "/Users/21107195/Desktop/google_transit/stop_times.txt"
and each from each line fgets trip_id,arrival_time,departure_time,stop_id,stop_sequence,pickup_type,drop_off_type,timepoint as
324155,06:32:00,06:32:00,23789,1,0,0,1 respectively
int main(int argc, char* argv[]){
//CONDITION FOR NUMBER OF ARGUMENTS
if(argc!=6){
printf("error: number of arguments must=5");
exit(EXIT_FAILURE);}
else{
//CONVERT LATITUDES AND LONGITUDES TO DOUBLE
double start_lat=atof(argv[2]);
double start_long=atof(argv[3]);
double end_lat=atof(argv[4]);
double end_long=atof(argv[5]);
//CHECK TO SEE IF ARGUMENT LATS AND LONGS ARE VALID
if(!valid_location(start_lat,start_long)||!valid_location(end_lat,end_long)){
printf("invalid starting location: lat=%lf long=%lf\n",start_lat, start_long);
exit(EXIT_FAILURE);
}
else{
printf("valid locations: start lat=%lf start long=%lf end lat=%lf end long=%lf\n",start_lat,start_long,end_lat,end_long);
int trip_id;
int hour;
int minute;
int stop_id;
int distance_start_stop1;
//DECLARE FILE POINTER
FILE *stoptimes;
//OPEN FILE stops.txt
stoptimes=fopen(STOPTIMES, "r");
if(stoptimes==NULL){
printf("cannot open file stoptimes.txt");
exit(EXIT_FAILURE);
}
//CREATE ARRAY TO STORE LINE OF stops.txt
char line[BUFSIZ];
//CONDITIONAL VARIABLE FOR WHILE LOOP
int count=0;
while(fgets(line, sizeof line, stoptimes)!=NULL){
if(count>0){
sscanf(line,"%d,%d:%d:%*d,%*d:%*d:%*d,%d,%*d,%*d,%*d,%*d",&trip_id,&hour,&minute,&stop_id);
printf(".%d\n",count);
distance_start_stop1=(int)haversine(start_lat,start_long,getlat(stop_id),getlong(stop_id));
printf("\n");
}
count++;
}
//CLOCE FILE STOPTIMES.TXT
fclose(stoptimes);
}
Everytime I run the code it runs for between 300 and 100 times depending on how many functions are called after using the sscanf function and returns a segmentation fault 11.
This is the code for
getlat(stop id)
where the stops file is
#define STOPS "/Users/21107195/Desktop/google_transit/stops.txt"
and the line should print out the following way
location_type, parent_station, stop_id, stop_code, stop_name, stop_desc, stop_lat, stop_lon, zone_id 0,,10000,10000,"Albany Hwy After Armadale Rd","",-32.1479054960,116.0201957650,4 where values a repsctively
double getlat(int stop_id){
int comstop_id;
double stop_lat;
//DECLARE FILE POINTER
FILE *stops;
//OPEN FILE stops.txt
stops=fopen(STOPS, "r");
//CREATE ARRAY TO STORE LINE OF stops.txt
char line[BUFSIZ];
//CONDITIONAL VARIABLE FOR WHILE LOOP
int count=0;
//WHILE LOOP GETTING LINES OF stop.txt
while(fgets(line, sizeof line, stops)!=NULL){
if(count>0){
if(isdigit(line[2])){
sscanf(line,"%*d,%*d,%d,%*d,%*100[^,],%*100[^,],%lf,%*lf,%*s",&comstop_id,&stop_lat);
}
else{
sscanf(line,"%*d,,%d,%*d,%*100[^,],%*100[^,],%lf,%*lf,%*s",&comstop_id,&stop_lat);
}
if(comstop_id==stop_id){
break;
}
}
count++;
}
printf("latitude:%lf/n",stop_lat);
fclose(stops);
return stop_lat;
}
**the fuction for getlong is the same except it retunr the value3 of the longitude
this is the function for haversine**
double haversine(double lat1, double lon1, double lat2, double lon2)
{
double deltalat = (lat2 - lat1) / 2.0;
double deltalon = (lon2 - lon1) / 2.0;
double sin1 = sin( degrees_to_radians(deltalat) );
double cos1 = cos( degrees_to_radians(lat1) );
double cos2 = cos( degrees_to_radians(lat2) );
double sin2 = sin( degrees_to_radians(deltalon) );
double x = sin1*sin1 + cos1*cos2 * sin2*sin2;
double metres = 2 * EARTH_RADIUS_IN_METRES * asin( sqrt(x) );
return metres;
}
double degrees_to_radians(double degrees){
return (degrees * M_PI / 180.0);
}
Related
I have a .dat file filled with ints and doubles that I need to populate an array of structures with, and I'm having issues figuring out the syntax.
Here is the file:
9383 8.86
2777 69.15
7793 83.35
5386 4.92
6649 14.21
2362 0.27
8690 0.59
7763 39.26
540 34.26
9172 57.36
5211 53.68
2567 64.29
5782 15.30
2862 51.23
4067 31.35
3929 98.02
4022 30.58
3069 81.67
1393 84.56
5011 80.42
6229 73.73
4421 49.19
3784 85.37
5198 43.24
8315 43.70
6413 35.26
6091 89.80
9956 18.73
6862 91.70
6996 72.81
Here is my code:
typedef struct student
{
double score;
int id;
char grades;
} Student;
int getScores(FILE *input, Student class);
void main(void)
{
char filename[] = "scores.dat";
FILE *input;
Student class[MAXNUM];
int numScores;
double average;
input = fopen("scores.dat", "r");
if (input == NULL)
{
printf("EOF");
exit(1);
}
}
int getScores(FILE *input, Student class)
{
double s;
int i, count = 0;
while(fscanf(input, "%d %lf", &i, &s) == 2)
{
class[count].score = s;
class[count].id = i;
count++;
}
My main issue lies in the while loop where I am trying to populate the array with the int and doubles of the scores.dat file.
I get the following error when I compile:
lab5.c:53:8: error: subscripted value is neither array nor pointer nor
vector
class[count].score = s;
^
lab5.c:54:8: error: subscripted value is neither array nor pointer nor
vector
class[count].id
Thank you for any help or tips.
Just change function getScores definition and declaration argument class from
`int getScores(FILE *input, Student class);`
to
`int getScores(FILE *input, Student *class);`
There is array of structure and a function that takes data from array of structure and print to file. But There is error : too few arguments to function.
How can I solve this problem ? I searched on internet but I did not find appropriate exapmle for me.
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct Student
{
char NUMBER[50];
char FIRST_NAME[50];
char LAST_NAME[50];
int QUIZ1;
int QUIZ2;
int MIDTERM1;
int MIDTERM2;
float HOMEWORK;
int FINAL;
float AVERAGE;
char LETTER_GRADE;
};
void WriteToFile(struct Student S, FILE *dosya)
{
fprintf(dosya,"%s %s %s %2.f %c",S.NUMBER,S.FIRST_NAME,S.LAST_NAME,S.AVERAGE,S.LETTER_GRADE);
}
int main() {
struct Student STUDENTS[80];
FILE *dosya1 = fopen("GRADES.txt","r");
FILE *dosya2 = fopen("pass.txt","w");
FILE *dosya3 = fopen("fail.txt","w");
int i=0;
if(dosya1==NULL){
printf("File can not be opened");
exit(1);
}
while(!feof(dosya1))
{
fscanf(dosya1,"%s%s%s%d%d%d%d%f%d",STUDENTS[i].NUMBER,STUDENTS[i].FIRST_NAME,STUDENTS[i].LAST_NAME,&STUDENTS[i].QUIZ1,&STUDENTS[i].QUIZ2,&STUDENTS[i].MIDTERM1,&STUDENTS[i].MIDTERM2,&STUDENTS[i].HOMEWORK,&STUDENTS[i].FINAL);
printf("%s %s %s %d %d %d %d %f %d",STUDENTS[i].NUMBER,STUDENTS[i].FIRST_NAME,STUDENTS[i].LAST_NAME,STUDENTS[i].QUIZ1,STUDENTS[i].QUIZ2,STUDENTS[i].MIDTERM1,STUDENTS[i].MIDTERM2,STUDENTS[i].HOMEWORK,STUDENTS[i].FINAL);
STUDENTS[i].AVERAGE = (STUDENTS[i].QUIZ1 / 10) + (STUDENTS[i].QUIZ2 / 10) + ((STUDENTS[i].MIDTERM1 / 100)*15) + ((STUDENTS[i].MIDTERM2 / 100)*15) + ((STUDENTS[i].FINAL / 10)*4) + (STUDENTS[i].HOMEWORK / 10);
if(STUDENTS[i].AVERAGE>=85 & STUDENTS[i].AVERAGE<=100)
STUDENTS[i].LETTER_GRADE = 'A';
else if(STUDENTS[i].AVERAGE<85 & STUDENTS[i].AVERAGE>=70)
STUDENTS[i].LETTER_GRADE = 'B';
else if(STUDENTS[i].AVERAGE<70 & STUDENTS[i].AVERAGE>=55)
STUDENTS[i].LETTER_GRADE = 'C';
else if(STUDENTS[i].AVERAGE<55 & STUDENTS[i].AVERAGE>=40)
STUDENTS[i].LETTER_GRADE = 'D';
else if(STUDENTS[i].AVERAGE<40 & STUDENTS[i].AVERAGE>=0)
STUDENTS[i].LETTER_GRADE = 'F';
if(STUDENTS[i].AVERAGE == 'F')
WriteToFile(STUDENTS.[i], dosya3);
else
WriteToFile(STUDENTS.[i], dosya2);
i++;
}
fclose(dosya1);
fclose(dosya2);
fclose(dosya3);
return 0;
}
There is a problem here:
WriteToFile(STUDENTS.[i], dosya3);
No need to put a dot, it should be:
WriteToFile(STUDENTS[i], dosya3);
(Same for the line that follows this one)
Im trying to scanf a structure from file input within a function, and print it using another function.
Ultimately I need to be able to print out the same information that I would from the code that I commented out, but doing so from the functions I have listed in the function prototypes declaration area. I only un-commented 2 of those so I could try baby steps to get something to scan and print using functions. The functions themselves are located at the very bottom.
To finish the scan_auto function, somehow I need to scanf 2 other structures that are part of the main structure. I assume I need to call the functions scan_date and scan_tank from scan_auto, however I am unsure how to do that properly.
Here is the code I have so far...
#include <stdio.h>
#define STRSIZE 20
/* Structure definitions */
typedef struct {
int month,
day,
year;
} date_t;
typedef struct {
double capacity,
current;
} tank_t;
typedef struct {
char make[STRSIZE],
model[STRSIZE];
int odometer;
date_t manuf,
purch;
tank_t tank;
} auto_t;
/* Function prototypes */
/*
int scan_date(date_t *date);
int scan_tank(tank_t *tank);
*/
int scan_auto(auto_t *vehicle, FILE *inp);
/*
void print_date(date_t date);
void print_tank(tank_t tank);
*/
void print_auto(auto_t vehicle);
int main()
{
auto_t vehicle;
int number=0,
i=0,
status=1;
FILE *inp = fopen("autos.txt","r"); /* defining file input */
/* Check to make sure input file is found and readable. */
if(inp==NULL){
printf("Error: Input file - autos.txt - not found!\n");
getch();
return 0;
}
printf("Vehicle Vehicle Odometer Date Date Tank Current\n");
printf("Make Model Reading Purchased Manufactured Capacity Fuel Level\n");
printf("\n----------------------------------------------------------------------------\n\n");
/*******************COMMENTED OUT*************************************
while(status>0){
status=fscanf(inp, "%s%s%d%d%d%d%d%d%d%lf%lf", vehicle.make,
vehicle.model,
&vehicle.odometer,
&vehicle.manuf.month,
&vehicle.manuf.day,
&vehicle.manuf.year,
&vehicle.purch.month,
&vehicle.purch.day,
&vehicle.purch.year,
&vehicle.tank.capacity,
&vehicle.tank.current);
if(status==11){
printf("%-10s%-9s%-10d%2d/%d/%-6d%2d/%d/%-8d%-11.1lf%.1lf\n", vehicle.make,
vehicle.model,
vehicle.odometer,
vehicle.manuf.month,
vehicle.manuf.day,
vehicle.manuf.year,
vehicle.purch.month,
vehicle.purch.day,
vehicle.purch.year,
vehicle.tank.capacity,
vehicle.tank.current);
i++;}
else if(status <11 && status>0){
printf("\nInvalid Input - The next line of data is corrupt.\n");
}
}
******************************************************************************/
scan_auto(&vehicle, inp);
print_auto(vehicle);
/*
print_auto(vehicle);
*/
getch();
return 0;
}
/*********************************************************************************/
int scan_date(date_t *date)
{
int result;
result=scanf("%d%d%d", &(*date).month,
&(*date).day,
&(*date).year);
if (result==3)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
double scan_tank(tank_t *tank)
{
int result;
result=scanf("%lf%lf", &(*tank).capacity,
&(*tank).current);
if (result==2)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
int scan_auto(auto_t *vehicle, FILE *inp)
{
int result;
result=fscanf(inp, "%s%s%d", (*vehicle).make,
(*vehicle).model,
&(*vehicle).odometer);
if (result==3)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
void print_auto(auto_t vehicle)
{
printf("%-10s%-9s%-10d", vehicle.make,
vehicle.model,
vehicle.odometer);
}
The text file (autos.txt) I am using....
Mercury Sable 99842 1 18 2001 5 30 1991 16 12.5
Mazda Navajo 123961 2 20 1993 6 15 1993 19.3 16.7
however I am unsure how to do that properly.
Can you elaborate on what you're unsure? If you're not sure how to assign value to struct member of struct, perhaps this sample code will help you? I combined all of the things together...
Oh, and I changed your *vehicle to *v to make it shorter and easier to read.
Also, since you're accessing member of struct pointer, why don't you use v->xxx instead of (*v).xxx ?
UPDATE 1: You asked how to do it separately. Here it is:
int scan_date(date_t *date, FILE *inp)
{
int result = fscanf(
inp,
"%d%d%d",
&(date->day),
&(date->month),
&(date->year));
return (result == 3);
}
int scan_tank(tank_t *tank, FILE *inp)
{
int result = fscanf(
inp,
"%lf%lf",
&(tank->capacity),
&(tank->current));
return (result == 2);
}
int scan_auto(auto_t *v, FILE *inp)
{
int result = fscanf(
inp,
"%s%s%d",
v->make,
v->model,
&(v->odometer));
result += scan_date(&(v->purch), inp);
result += scan_date(&(v->manuf), inp);
result += scan_tank(&(v->tank), inp);
return (result == 11); // return 0 if true
}
I'm trying to generate a tabulation file for 1000 data points using this code below, the program works when I don't add the File Creation and Opening section, but when this is added the program doesn't end once I've entered the inputs.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void mapfun(int imap, double *c, double xi, double yi, double *xo, double *yo);
void mapspin(int imap, double *c, int nspin, double *xo, double *yo);
int main(){
/* Defining values */
int imap;
int nspin=1000;
double xo;
double yo;
double c[4];
float mu;
/* Ask for an input of 1 or 2 */
printf("Input 1 or 2\n");
scanf("%d", &imap);
/* Assigning c when input is 1 and assigning mu */
if(imap==1){
c[1]=0.04;
c[2]=0.04;
printf("Input a value for mu between 2.8 and 3.8\n");
scanf("%e:%d", &mu);
if(mu>2.8 && mu<3.8){
c[0]=mu;
c[3]=mu;
} else{
printf("Invalid value for mu\n");
exit(0);
}
/* Assigning c when input is 2 and assigning mu */
} else if(imap==2){
c[1]=1;
c[2]=1;
printf("Input a value for mu between 1 and 3\n");
scanf("%e:%d", &mu);
if(mu>1 && mu<3){
c[0]=mu;
c[3]=mu;
} else{
printf("Invalid value for mu\n");
exit(0);
}
} else{
printf("Invalid value entered\n");
exit(0);
}
mapspin(imap, c, nspin, &xo, &yo);
/*File Creation and Opening*/
FILE*orbit;
orbit = fopen("orbit.dat", "rb+");
if(orbit == NULL) {
/* creates file if not there */
orbit = fopen("orbit.dat", "wb");
}
double xi=xo;
double yi=yo;
int i;
for(i=0; i<nspin; i+1){
mapfun(imap, c, xi, yi, &xo, &yo);
xi=xo;
yi=yo;
fprintf(orbit, "xo = %3f, yo = %3f\n", xo, yo);
}
orbit = fopen("orbit.dat", "r");
printf("c[0]= %.2f, c[1]= %.2f, c[2]= %.2f, c[3]= %.2f\n", c[0], c[1], c[2], c[3]);
exit(0);
}
Main problem:
The for loop is not well formed.
for(i=0; i<nspin; i+1){
^^^ This does not change the value of i
^^^ That explains why the loop never ends.
Use:
for(i=0; i<nspin; ++i){
Another issue:
I don't understand why you have the line:
orbit = fopen("orbit.dat", "r");
That seems to be an unnecessary line.
Additional Info
The following program illustrates how you can accidentally modify a value in a function called from main.
#include <stdio.h>
void foo(int* x)
{
x[1] = 20;
}
int main()
{
int a = 10;
int b;
printf("Value of a before call to foo: %d\n", a);
foo(&b); // foo has no direct access to "a" but it can
// indirectly access "b" by using an out of
// bounds index.
printf("Value of a after call to foo: %d\n", a);
}
I built the program using gcc 4.8.2. When I run the program, the output is:
Value of a before call to foo: 10
Value of a after call to foo: 20
You write ascii/text into a binary open file with the boption. I think if the file exists you just have to append by using a fopen option and ths will create the file if it doesn't exists:
orbit = fopen("orbit.dat", "a");
if(orbit == NULL) {
//IO Error cannot open the file in append mode or create the file
exit(1);
}
And don't reuse a file descriptor variable without doing fclose call:
fprintf(orbit, "xo = %3f, yo = %3f\n", xo, yo);
//Fprintf Return value must be checked too
}
if( 0 != fclose( orbit ) )
{
//IO Error cannot close the opened file
exit(1);
}
orbit = fopen("orbit.dat", "r");
if( orbit == NULL )
{
//IO Error cannot open the file for reading
exit(1);
}
Each IO call return value/errno must be checked!
And the main problem reported by #r-sahu is the for loop.
Hi I am trying to count in note data from keyboard and write the data to a text file which will subsequently be read out of and played back as notes.
I seem to only be able to write one line of numbers to the text file and help would be most appreciated. Sorry i still have some of my function code included in the global.
#define SEQ_NOTENUM 8
#define SEQ_NUM 2
// structures //
typedef struct
{
int notenumber;
int velocity;
}NoteData;
typedef struct
{
float frequency;
float amplitude;
} OscData;
// functions //
float mtof(int note);
// originally in main //
OscData noteToOsc(NoteData note);
int setcount, count;
int currentset;
OscData osc;
int main()
{
int key, vel;
NoteData sequence[SEQ_NUM][SEQ_NOTENUM];
OscData noteToOsc(NoteData note);
FILE* Sequence1;
// START PROGRAM RECORD -- WRITE an IF/ELSE to run program -
dummy line atm//
aserveGetVelocity();
Sequence1 = fopen ("sequence1.txt", "w");
if (Sequence1 == NULL)
{
printf("file Error\n");
}
else
{
for(setcount = 0; setcount < SEQ_NUM; setcount++)
{
printf("--- Please enter sequence %d (%d notes)...\n",
setcount, SEQ_NUM);
count = 0;
while(count < SEQ_NOTENUM)
{
key = aserveGetNote();
vel = aserveGetVelocity();
if(vel > 0)
{
sequence[setcount][count].notenumber = key;
sequence[setcount][count].velocity = vel;
fprintf(Sequence1, "note %d - %d/%d\n", count, key,
vel);
count++;
}
fclose(Sequence1);
}
return 0;
}
}
The code's indentation is messed up, obscuring the fact that fclose(Sequence1) is closing the file after only one pass through the inner loop. You probably want to move that to somewhere further down.