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.
Related
Hello everybody I'm with problems to make my program work with GSL - root finding. I'm trying find a solution to my equation. I'm looking solutions for a data with 64 lines, but in some specific lines the program can't continue, maybe because a good solution is not existent. But I want that the program just skip line when he don't find a solution. But my program just stop sometimes and appear this message:
gsl: brent.c:74: ERROR: endpoints do not straddle y=0
passou1passou2passou3Default GSL error handler invoked.
Abort trap: 6
So, I did some prints to check where exactly my program stop and I found that is in gsl_root_fsolver_set(s,&F, x_lo, x_hi), but I didn't find how print this value or what this function give to me.
My program is here, thanks everybody!
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_roots.h>
#include "demo_fn.h"
#include "demo_fn.c"
int
main (void)
{
double NT, c;
c = 64.0/2.0;
char url[]="charm.txt";
double corr, core, a[64][3];
int nt, i = 0;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o arquivo\n");
else
while( (fscanf(arq,"%lf %lf %i\n", &corr, &core, &nt))!=EOF ) {
a[i][0]=corr;
a[i][1]=core;
a[i][2]=nt;
i++;
//printf("%lf, %lf, %i\n",corr, core, nt);
}
fclose(arq);
for (i= 0; i < 64; i++)
{
int status;
int iter = 0, max_iter = 200;
const gsl_root_fsolver_type *T;
gsl_root_fsolver *s;
double r = 0, r_expected = 4.0;
double x_lo = 0.0001, x_hi = 4.0;
double ratio1, ratio2;
ratio1 = a[i][0]/a[i+1][0];
ratio2 = a[i+1][0]/a[i+2][0];
printf ("ratio1: %lf, ratio2: %lf", ratio1, ratio2);
printf ("\n");
// if (ratio1*ratio2 > 0)
// {
printf("C(n_t) : %.15lf -- loop index : %i ----- ratio: %lf \n", a[i][0],i, ratio1);
gsl_function F;
struct quadratic_params params = {a[i][0], i, c, i+1, a[i+1][0]};
F.function = &quadratic;
printf ("passou1");
F.params = ¶ms;
T = gsl_root_fsolver_brent;
printf ("passou2");
//T = gsl_root_fsolver_bisection;
s = gsl_root_fsolver_alloc (T);
printf ("passou3");
gsl_root_fsolver_set (s, &F, x_lo, x_hi);
printf ("passou4");
printf ("using %s method\n", gsl_root_fsolver_name (s));
printf ("%5s [%9s, %9s] %9s %10s %9s\n", "iter", "lower", "upper", "root", "err", "err(est)");
do
{
iter++;
status = gsl_root_fsolver_iterate (s);
r = gsl_root_fsolver_root (s);
x_lo = gsl_root_fsolver_x_lower (s);
x_hi = gsl_root_fsolver_x_upper (s);
status = gsl_root_test_interval (x_lo, x_hi,0, 0.001);
if (status == GSL_SUCCESS)
{
printf ("Converged:\n");
}
printf ("%5d [%.7lf, %.7lf] %.7lf %+.7lf %.7lf\n", iter, x_lo, x_hi, r, r - r_expected, x_hi - x_lo);
}
while (status == GSL_CONTINUE && iter < max_iter);
gsl_root_fsolver_free (s);
// }
printf("\n");
}
return 0;
}
Gabriela. The output has already told you why you program is wrong. Endpoints do not straddle y=0.
The root bracketing algorithms described in this section require an initial interval which is guaranteed to contain a root—if a and b are the endpoints of the interval then f(a) must differ in sign from f(b).
The above is from the manual of gsl, so if the end points have the same sign, the program will stop and tell you this error.
Have you ever tried the error handler in gsl. In the chapter 3 of the manual, they offer a function called gsl_set_error_handler_off(), if you place this function just before gsl_root_fsolver_set(s,&F, x_lo, x_hi), and you can assign this function to an int type variable, let's say status, as we can see from the manual that it(gsl_root_fsolver_set(s,&F, x_lo, x_hi)) is an int function, then if you print out the value of status, and check it with gsl_errno.h file, you will know what that value mean.
This gsl_set_error_handler_off() can dismiss the abortion from execution.
as for you code, you should do the following:
add #include <gsl/gsl_errno.h>
add gsl_set_error_handler_off() before status=gsl_root_fsolver_set(s,&F, x_lo, x_hi)
use the value of status like the following loop of you program to make little changes of you end points,to expand or narrow or translate your interval, when they satisfied the initial condition, the program will run again
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);
}
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.
I wrote a C code which extracts data from a binary file which has size around 1 GB. There are 101 (0 to 100)configurations and the C code extracts data for a selected configuration and writes the output in a file. To compile the C code, I give user defined configuration number like this in the terminal:
gcc binary2textperconfig.c -o f.out
./f.out proton-p000-1.bin out1.txt
Then it asks for configuration number:
Enter the configuration number:
After that the data is written in file "out0.txt". Now I want to run this code for all 101 configurations and write those data to files "out0.txt", "out1.txt",...., "out100.txt" etc. I don't know how to do this without typing the configuration numbers 101 times in the terminal. Could any one please help me? Here is my C-code:
#include <stdio.h>
#include<complex.h>
#include<math.h>
#include <stdlib.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_matrix.h>
typedef double complex dcomplex;
//Data is converted to Bigendian using io-general
double constructfloat(char bytes[sizeof(double)/2], int order)
{
double dRes;
char *pc;
int i;
if (order == 0)
for(i=0, pc = (char*) &dRes; i<=sizeof(double)-1 ; i++, pc++)
(*pc) = bytes[i];
else
for(i=sizeof(double)-1, pc = (char*) &dRes; i>=0; i--, pc++)
(*pc) = bytes[i];
return dRes;
}
int main(int argc, char *argv[]){
int configcount = 101;
int mcount = 14;
int tcount = 64;
int d1count = 4;
int d2count = 4;
int pcount = 45;
int userci;
int usermi;
int userpi;
// number of complex numbers per configuration
int unitcountperconfig =(mcount*tcount*d1count*d2count*pcount);
// initialize loop index variables
int ci = 0; //config
int mi = 0; //mass
int ti = 0;
int d1i = 0;
int d2i = 0;
int pi = 0; //momentum
// for holding the result of read operation ( how many units have been read)
int result;
// for holding the data read from file
char * cbuff;
// input file handle from where binary data is read
FILE * fin = fopen(argv[1],"rb");
// if the input file cannot be read for reading, close opened file handles, show an error message to the user, and exit
if (fin==NULL)
{
fputs ("Error opening input file\n",stderr);
exit (1);
}
FILE * fout = fopen(argv[2],"wt");
// if the output file cannot be opened for writing, close opened file handles, show an error message to the user, and exit
if (fout==NULL)
{
fclose(fin);
fputs ("Error opening output file\n",stderr);
exit (1);
}
// take input from the user
// take input from the user
printf("Enter the configuration number: ");
scanf("%d",&userci);
// allocate memory to contain the chunk of data for a time slice:
cbuff = (char*)malloc(sizeof(dcomplex)*unitcountperconfig );
// show error message and exit if memory allocation failed
if(cbuff == NULL)
{
fputs("Buffer allocation failed.", stderr);
exit(1);
}
// variable to hold a complex number read from the file
dcomplex aComplexNumber;
dcomplex sumpertimeslice[tcount];
// loop on time slices
for( ci = 0; ci< configcount ; ci++){
// index of the complex number being read
unsigned int cNumberIdx = 0;
// debugging message
printf("reading data for configuration: %d\n",ci);
// perform read operation to read the desired chunk of data
result = fread(cbuff, sizeof(char), sizeof(dcomplex)*unitcountperconfig, fin );
// if size of data successfully read is not equal to what we wanted to read, notify the user and exit
if (result != sizeof(dcomplex)*unitcountperconfig) {
fputs ("data reading error\n",stderr);
exit (3);
}
double realP;
double imagP;// variable to hold real and imaginary part of the complex number
double realPSum;
double imagPSum;// variable to hold sum of real and sum of imaginary part of the current sum per time slice
for (mi =0; mi< mcount ; mi++){
for (ti =0; ti< tcount ; ti++){
// array to hold trace for each time slice
sumpertimeslice[ti] = 0.0 + 0.0*_Complex_I;
for (d1i =0; d1i < d1count ; d1i++){
for (d2i =0; d2i < d2count ; d2i++){
for (pi =0; pi < pcount ; pi++){
aComplexNumber = constructfloat( &cbuff[cNumberIdx], 0 ) + constructfloat( &cbuff[cNumberIdx+ ((int)sizeof(dcomplex))/2 ], 0 )*_Complex_I;
if (ci== userci)
{
cNumberIdx += (int)sizeof(dcomplex);
if (cimag(aComplexNumber)>0)
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e+%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
else
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
}
}
}
}
}
}
}
// free the allocated memory
free(cbuff);
// close the opened file handles
fclose(fin);
fclose(fout);
//fclose(complexNumberFileP);
}
Use the seq utility to generate a list of number between 0 & 100, and send it as a string to stdin.
for CNUMBER in $(seq 0 100); do
./f.out proton-p000-1.bin out${CNUMBER}.txt <<< "${CNUMBER}"
done
or
for CNUMBER in $(seq 0 100); do
echo $CNUMBER | ./f.out proton-p000-1.bin out${CNUMBER}.txt
done
I have a file with this format:
0.4
0.3
0.2
0.4
I need to create a new file with this format:
1 2
0.4 1 0
0.5 1 0
0.3 0 1
...
I wrote this function
void adapta_fichero_serie(char file_input[50],char file_output[50], int np)
{
FILE* val_f=fopen(file_input,"r");
FILE* out_f=fopen(file_output,"w+");
float temp[np+1];
float tempo;
int i=0;
int uno=1;
int flag=0;
int due=2;
int zero=0;
int file_size;
fprintf(out_f,"%d %d\n", np, due );
while(!feof(val_f))
{
if(flag==0)
{
for(i=0;i<np;i++)
{
fscanf(val_f,"%f" ,&tempo);
temp[i]=tempo;
flag=1;
}
}
fscanf(val_f,"%f",&tempo);
temp[np]=tempo;
for(i=0;i<np;i++)
{
fprintf(out_f,"%f\t",temp[i]);
}
if(temp[np-1]<=temp[np])
fprintf(out_f,"%d\t%d ", uno, zero);
else fprintf(out_f,"%d\t%d\n", zero, uno);
for(i=0;i<np;i++)
{
tempo=temp[i+1];
temp[i]=tempo;
}
}
close(out_f);
close(val_f);
}
and create new file with correct format but when i try to read this new file, the reading stopping at line 315 but the file is of 401 line.
Can you help me? I hope my question is easy to understand!
Just to record your solution from the comments, use fclose instead of close and make sure to pay attention to your compiler warnings as they would have pointed this out.
Not sure what your algorithm should do. Here is my view of it :)
void adapta_fichero_serie(const char *file_input, const char *file_output)
{
float n_prev, n_cur; // Processed values as we read them
FILE *in, *out; // Input-output files
n_prev = 0; // Initial value for the first element to compare with
in = fopen(file_input, "rt"); // open read only in text mode
out = fopen(file_output, "wt+"); // append in text mode
fprintf(out, "1\t2\n\n"); // write header: 1 <TAB> 2 <CR><CR>
while (fscanf(in, "%f", &n_cur) == 1) // run loop as long as we can read
{
fprintf(out, n_cur > n_prev ? "1\t0\n" : "0\t1"); // print depending on comparison
n_prev = n_cur; // save value for the next iteration
}
fclose(in);
fclose(out);
}