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);
}
Related
so I'm trying to search through a file for a sequence of float-numbers. the end sequence is 0.0 for each block.
I want to be able to select the piece of numbers and treat them as individual strings so to speak. As you can see, it's quite convenient to always being able to chose 0.0 as your end-limit of your selection range, but thus far i haven't been able to accomplish this.
Any help would be greatly appreciated!
current code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
#define TRUE 1 //for convenience later on
#define FALSE 0
#define CHUNK 1024 /* read 1024 bytes at a time, will be used later*/
char buf[CHUNK];
long *n;
n=NULL;
FILE *in_file = fopen("Measurements.txt","r");
if(in_file == NULL){ //test for files not executing again.
printf("File could not be read/found...");
exit(1);
}
//searching for end of string-block
fscanf(in_file,"%[^0.0];",n);
puts(&n); // trying to see if the fscanf function actually selected the right numbers
if(in_file){
fclose(in_file);
}
Chunk of code in the Measurement.txt file:
210.5 210.9 213.8 209.3 214.7 214.2 214.4 211.8
213.9 213.6 214.5 214.3 213.2 215.5 210.9 212.3
215.4 212.4 210.6 210.4 216.2 209.9 211.4 213.7
213.9 209.2 210.4 211.8 215.8 216.4 216.1 209.6
217.5 209.8 210.8 216.4 209.4 217.0 212.3 217.7
216.5 214.4 217.2 215.5 217.6 211.6 211.8 213.7
217.0 211.3 217.2 211.2 210.2 215.1 217.2 211.9
216.8 217.5 212.1 217.5 212.9 217.2 211.0 215.2
216.8 211.6 210.9 216.4 210.8 213.0 210.9 217.2
217.3 216.2 213.4 209.2 215.9 212.1 210.5 211.3
215.5 212.7 216.6 214.2 215.9 209.4 212.1 217.6
213.2 213.5 217.6 214.6 211.1 209.6 213.6 213.7
209.2 210.4 214.7 215.0 0.0
This pattern is repeated 4-5 times (but should be treated as it could occur an arbitrary amount of times, ofc with different values but always ending with 0.0).
This:
fscanf(in_file,"%[^0.0];",n);
Does not do what you think it does. In particular, the format %[^0.0]; does not select "numbers other than 0.0." You should keep it simple:
double num;
while (fscanf(in_file, "%f", &num) == 1) {
if (num == 0.0) {
// we are at the end of a block
}
}
Note that I also used double instead of long because you have floating-point inputs.
I'd try something that starts out like this, assuming the file fits in memory and contains nothing but text (no NUL characters), numbers are separated by space characters, and that the only numbers that match 0.0 signify the end of a block of numbers:
void addToBlock( double num )
{
// add a value to a block of numbers
// use a global array or similar data structure
}
processBlock()
{
// process a block of numbers
// and then reset it to start over
}
int main( int argc, char **argv )
{
// read entire contents into memory (could also just mmap
// the file but that doesn't guarantee you can treat the
// contents as a NUL-terminated string
struct stat sb;
int fd = open( argv[ 1 ], O_RDONLY );
fstat( fd, &sb );
char *content = malloc( sb.st_size + 1 );
read( fd, content, sb.st_size );
close( fd );
// NUL-terminate our data so it's a string
content[ sb.st_size ] = '\0';
// start at the beginning, convert each number we find
// into a double, loop until the conversion fails
char *current = content;
for ( ;; )
{
char *last;
double num = strtod( current, &last );
// if last == current, the conversion failed so
// break the loop
if ( current == last )
{
break;
}
// match your pattern here - keep a circular buffer or
// an array
if ( 0.0 == num )
{
processBlock();
}
else
{
addToBlock( num );
}
// skip to the next number
current = last;
}
free( content );
return( 0 );
}
You'd need to add some more error checking there, especially for the read() call.
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.
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
Hello fellow programmers i am trying to understand what exactly is happening in this area of my code.
Problem: I read some contents into a file , then i am trying to read back the contents out of the file just to make sure its the right contents i had put into the file but it is not giving me the correct output, so i am a little confused here is the code(saved content as binary) :
typedef struct acc
{
int id_no;
int pin;
float bal;
}Acc;
int Crte_acc(FILE *flepss)
{
int i,cnt;
Acc user[1000];
cnt = 1000;
for (i=1;i<1000;i++)
{
cnt+=1;
user[i].id_no = cnt;
user[i].bal=1000;
user[i].pin=0000;
fwrite(&user[i].id_no,sizeof(int),1,flepss);
fwrite(&user[i].pin,sizeof(int),1,flepss);
fwrite(&user[i].bal,sizeof(int),1,flepss);
}
return fclose(flepss);
}
Yea so above is the code that takes a file pointer and a count to keep the id to increase by 1 ( 1001,1002 etc), bal and pin required that i set the var with those digits.So i am wondering whats the problem, this is the code of me displaying the contents.
void DisplyFile()
{
FILE *dfp;
int x;
Acc pruser[1000];
dfp = fopen("Account.dat","rb");
fseek(dfp,0,SEEK_SET);
while (1)
{
if(!feof(dfp))
{
for (x=1;x<1000;x++)
{
fread(&pruser[x].id_no,sizeof(pruser[x].id_no),1,dfp);
fread(&pruser[x].pin,sizeof(pruser[x].pin),1,dfp);
fread(&pruser[x].bal,sizeof(pruser[x].bal),1,dfp);
printf("%d ",pruser[x].id_no);
printf("%d ",pruser[x].pin);
printf("%.2f\n\n",pruser[x].bal);
}
}
else
{
break;
}
}
}
EDIT: By contents coming out wrong i mean , giving me garbage values as to show that my write to file was not saved.
The problem may come from a missing fclose or fopen...
There is almost nothing to do to build something that works.
Three things to check :
-Does a fopen correspond to a fclose ?
-Are opening types similar ? Are both "wb" and "rb" used ?
-Another point is fwrite(&user[i].bal,sizeof(int),1,flepss);...bla is a float. float and int may have the same sizeof, but...It is safer to assume that it is not always the case !
#include <stdio.h>
typedef struct acc
{
int id_no;
int pin;
float bal;
}Acc;
int Crte_acc()
{
FILE *flepss;
int i,cnt;
Acc user[10];
cnt = 1000;
flepss = fopen("Account.dat","wb");
for (i=1;i<10;i++)
{
cnt+=1;
user[i].id_no = cnt;
user[i].bal=10;
user[i].pin=0000;
fwrite(&user[i].id_no,sizeof(int),1,flepss);
fwrite(&user[i].pin,sizeof(int),1,flepss);
fwrite(&user[i].bal,sizeof(float),1,flepss);
}
return fclose(flepss);
}
void DisplyFile()
{
FILE *dfp;
int x;
Acc pruser[10];
dfp = fopen("Account.dat","rb");
fseek(dfp,0,SEEK_SET);
while (1)
{
if(!feof(dfp))
{
for (x=1;x<10;x++)
{
fread(&pruser[x].id_no,sizeof(pruser[x].id_no),1,dfp);
fread(&pruser[x].pin,sizeof(pruser[x].pin),1,dfp);
fread(&pruser[x].bal,sizeof(pruser[x].bal),1,dfp);
printf("%d ",pruser[x].id_no);
printf("%d ",pruser[x].pin);
printf("%.2f\n\n",pruser[x].bal);
}
}
else
{
break;
}
}
fclose(dfp);
}
int main()
{
Crte_acc();
printf("file printed\n");
DisplyFile();
printf("end file read 1\n");
DisplyFile();
printf("end file read 2\n");
return 0;
}
To compile : gcc main.c -o main
Bye,