I encounter segmenatation fault in fread while I am reading 1500 or more ethernet data packets. Here "test2" is the binary file whose file size is 22.6MB. 1132 is the number of useful data points in each packet and 142 points carries header information hence it is skipped.
here is the main program:
void main()
{
int count;
FILE *fp;
long file_size;
unsigned char rawdata[1132];
fp=fopen("test2","rb");
if(fp==-1)
{
printf("unsucessful");
exit(0);
}
long int before=ftell(fp);
fseek(fp,0,SEEK_END);
file_size=ftell(fp);
rewind(fp);
long int after=ftell(fp);
//skip first 142 bytes(header information)since its not required
fseek(fp,142,SEEK_SET);
long int s=ftell(fp);
int length_of_fft=4096;
int buffer_width=128;
int buffer_depth=1024;
int k,aa,payloadindex=0,l=0,j,a;
int no_of_data_pts_to_be_read=1132;
int no_of_ethernet_pkts_to_be_read=1500;
int q=no_of_ethernet_pkts_to_be_read*buffer_depth;
unsigned char payload[q];
unsigned int payloadint[q];
int no_of_data_pks_read=0;
int reading_for_first_time=1;
unsigned char data_from_file[no_of_ethernet_pkts_to_be_read][buffer_depth];
int addr_offset_in_inarray=0;
int udp_counter_values[no_of_ethernet_pkts_to_be_read];
unsigned int rawdataint[1132];
long int size;
count=0;
for(a=0; a<no_of_ethernet_pkts_to_be_read; a++)
{
int p=fread(rawdata,1 ,sizeof(rawdata), fp);
count=p;
//----------- to check if all data points have been read, i,e the pointer must be at a position wich is a multiple of 1132 which is[(1274-142=1132)*(a+1)],( since 142 bytes were skipped in the beginning )
printf("\n\n %d\t Start=%x\t\t Stop=%x\t Count=%d\t Address=%x",no_of_data_pks_read, rawdata[0], rawdata[sizeof(rawdata)-1],count,
ftello(fp));
if(count==no_of_data_pts_to_be_read)
{
printf("\nNumber of data points read in packet %d (of %d) is %d ",no_of_data_pks_read, no_of_ethernet_pkts_to_be_read, count);
reading_for_first_time=0;
//--------------converting char array rawdata into int array and then call udp
for(i=0;i<1132;i++)
rawdataint[i]=rawdata[i]-'\0';
udp_counter_values[a]=check_UDPpacketCount(&addr_offset_in_inarray, &rawdataint,10,no_of_data_pks_read,1132);
// printf("\n--------udp:: %d ",udp_counter_values[a]);
//-----------------create new mat and compute payload and put the contents of array rawwdata into the respective row of the new matrix
int k,t,w,time=0;
for(k=0,l=addr_offset_in_inarray;l<sizeof(rawdata),k<1024;k++,l++)
{
data_from_file[no_of_data_pks_read][k]=rawdata[l];
// printf("\n datafile:%d",data_from_file[no_of_data_pks_read][k]);
}
for(t=0;t<1024;t++)
{
payload[payloadindex++]=data_from_file[no_of_data_pks_read][t];
}
no_of_data_pks_read++;
}
else
{
count=0;
printf("\n not equal, exiting ");
exit(0);
}
}
//------convert payload to int array and send to data extraction function
for(i=0;i<sizeof(payload);i++)
{
payloadint[i]=payload[i]-'\0';
}
printf(" sizepayload: %d", sizeof(payload));
size=sizeof(payload);
data_extraction(size, payloadint,buffer_depth,buffer_width,length_of_fft);
printf("\n s:%d",file_size);
printf("\n ft:%x",ftell(fp));
printf("\n****----end----****");
fclose(fp);
}
As it has already been mentioned that you might be using up all your stack, try making all statically allocated variables global or use dynamic allocation. That should improve your situation.
fopen() returns a NULL pointer upon error, not -1.
If fopen has failed, you go on and do file operations with a NULL pointer.
This is wrong:
fp=fopen("test2","rb");
if(fp==-1)
{
printf("unsucessful");
exit(0);
}
It should be (and watch my use of whitespace)
fp = fopen("test2", "rb");
if (fp == NULL) {
printf("Could not open test2\n"); /* A meaningful error message */
exit(0);
}
There are few errors in your code.
1.you need check fp==NULL instead of fp==-1 when ever fopen() fails it returns NULL
2.in for loop you are using comma ,I guessing that is AND.
for(k=0,l=addr_offset_in_inarray;l<sizeof(rawdata),k<1024;k++,l++)
^
for(k=0,l=addr_offset_in_inarray;((l<sizeof(rawdata) )&& (k<1024));k++,l++)
^^
3.did not declared variable i.
warnings need to remove
You did not used many variables even though they are initialized with values
type mismatch while printing.
MODIFIED CODE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int count,i;
FILE *fp;
long file_size;
unsigned char rawdata[1132];
fp=fopen("test2","rb");
if(fp==NULL)
{
printf("unsucessful");
exit(0);
}
long int before=ftell(fp);
fseek(fp,0,SEEK_END);
file_size=ftell(fp);
rewind(fp);
long int after=ftell(fp);
//skip first 142 bytes(header information)since its not required
fseek(fp,142,SEEK_SET);
long int s=ftell(fp);
int length_of_fft=4096;
int buffer_width=128;
int buffer_depth=1024;
int k,aa,payloadindex=0,l=0,j,a;
int no_of_data_pts_to_be_read=1132;
int no_of_ethernet_pkts_to_be_read=1500;
int q=no_of_ethernet_pkts_to_be_read*buffer_depth;
unsigned char payload[q];
unsigned int payloadint[q];
int no_of_data_pks_read=0;
int reading_for_first_time=1;
unsigned char data_from_file[no_of_ethernet_pkts_to_be_read][buffer_depth];
int addr_offset_in_inarray=0;
int udp_counter_values[no_of_ethernet_pkts_to_be_read];
unsigned int rawdataint[1132];
long int size;
count=0;
for(a=0; a<no_of_ethernet_pkts_to_be_read; a++)
{
int p=fread(rawdata,1 ,sizeof(rawdata), fp);
count=p;
//----------- to check if all data points have been read, i,e the pointer must be at a position wich is a multiple of 1132 which is[(1274-142=1132)*(a+1)],( since 142 bytes were skipped in the beginning )
printf("\n\n %d\t Start=%x\t\t Stop=%x\t Count=%d\t Address=%x",no_of_data_pks_read, rawdata[0], rawdata[sizeof(rawdata)-1],count,(unsigned int) ftell(fp));
if(count==no_of_data_pts_to_be_read)
{
printf("\nNumber of data points read in packet %d (of %d) is %d ",no_of_data_pks_read, no_of_ethernet_pkts_to_be_read, count);
reading_for_first_time=0;
//--------------converting char array rawdata into int array and then call udp
for(i=0;i<1132;i++)
rawdataint[i]=rawdata[i]-'\0';
udp_counter_values[a]=check_UDPpacketCount(&addr_offset_in_inarray, &rawdataint,10,no_of_data_pks_read,1132);
// printf("\n--------udp:: %d ",udp_counter_values[a]);
//-----------------create new mat and compute payload and put the contents of array rawwdata into the respective row of the new matrix
int k,t,w,time=0;
for(k=0,l=addr_offset_in_inarray;(l<sizeof(rawdata)|| k<1024);k++,l++)
{
data_from_file[no_of_data_pks_read][k]=rawdata[l];
// printf("\n datafile:%d",data_from_file[no_of_data_pks_read][k]);
}
for(t=0;t<1024;t++)
{
payload[payloadindex++]=data_from_file[no_of_data_pks_read][t];
}
no_of_data_pks_read++;
}
else
{
count=0;
printf("\n not equal, exiting ");
exit(0);
}
}
//------convert payload to int array and send to data extraction function
for(i=0;i<sizeof(payload);i++)
{
payloadint[i]=payload[i]-'\0';
}
printf(" sizepayload: %ld", sizeof(payload));
size=sizeof(payload);
data_extraction(size, payloadint,buffer_depth,buffer_width,length_of_fft);
printf("\n s:%ld",file_size);
printf("\n ft:%x",(unsigned int)ftell(fp));
printf("\n****----end----****");
fclose(fp);
}
If you're on a Unix-like platform, you could replace the fopen, fread, fseek calls with the raw system-calls just to see what happens.
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
int fd = open("test2", O_RDONLY);
if (fd < 0) {
printf("Could not open test2\n");
exit(0);
}
And then use read() instead of fread(), lseek() instead of fseek() ,etc.
Related
I'm trying to initialize array *dip inside "leggif1", inside it if you do a print it's all normal but if you try to print in the main, after the initialization, everything loses its values.
Same thing happen with ADT of first grade "Divisione" and i can't understand why (even though they are passed "by reference" thanks to their pointers).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int matricola;
char nome[20+1],cognome[20+1];
int comp[4];
}dipendente;
typedef struct divisione *Divisione;
struct divisione{
dipendente *dip;
char nome[10+1];
int terna[4][3]; //numero minimo di addetti,competenza minima totale, competenza ottimale totale
//per ognuna delle 4 tipologie
};
void leggif1(dipendente *dip, char *filename);
int leggif2(Divisione *Div, char *filename);
void DIVstampa(Divisione *Div,char *filename,int D);
Divisione DIVinit();
void DIVfree(Divisione *Div);
int main(int argc,char **argv) {
dipendente *dip;
Divisione *Div;
leggif1(dip,argv[1]);
int D=leggif2(Div, argv[2]);
DIVstampa(Div,"stdout",D);
return 0;
}
void leggif1(dipendente *dip, char *filename) {
FILE *fp=fopen(filename,"r");
int i,N;
fscanf(fp,"%d",&N);
dip=malloc(N*sizeof(dipendente));
for(i=0;i<N;i++)
fscanf(fp,"%d %s %s %d %d %d %d",&dip[i].matricola,dip[i].nome,dip[i].cognome,
&dip[i].comp[0],&dip[i].comp[1],&dip[i].comp[2],&dip[i].comp[3]);
}
int leggif2(Divisione *Div, char *filename) {
FILE *fp=fopen(filename,"r");
int i,j,D;
fscanf(fp,"%d",&D);
Div=malloc(D*sizeof(Divisione));
for(i=0;i<D;i++)
Div[i]=DIVinit();
for(i=0;i<D;i++) {
fscanf(fp, "%s", Div[i]->nome);
for (j = 0; j < 4; j++)
fscanf(fp, "%d %d %d", &Div[i]->terna[j][0], &Div[i]->terna[j][1], &Div[i]->terna[j][2]);
}
return D;
}
void DIVstampa(Divisione *Div, char *filename, int D) {
FILE *fp;
if(strcmp(filename,"stdout")==0)
fp=stdout;
else
fp=fopen(filename,"w");
int i,j;
for(i=0;i<D;i++) {
fprintf(fp,"%s\n", Div[i]->nome);
for(j=0;j<4;j++)
fprintf(fp,"%d %d %d\n", Div[i]->terna[j][0], Div[i]->terna[j][1], Div[i]->terna[j][2]);
}
}
Divisione DIVinit(){
Divisione Div=malloc(sizeof (*Div));
return Div;
}
void DIVfree(Divisione *Div){
free(Div);
}
The leggif1 function ignores the value of dip and assigns it a new value. That value is never returned to main.
The type of dip is dipendente* and when called in main the value of the pointer is passed to the function. Overwriting that local copy in the function does not affect the value of the pointer in main.
C only has 'call by value', always make sure you known what that value represents.
This can be solved by returning the dip from the function instead of taking it as a parameter:
dipendente* leggif1(char *filename)
{
//open file and read N
dipendente *dip = malloc(N * sizeof *dip);
if (!dip) {
return NULL;
}
// read in the data
return dip;
}
another way is to use a dipendente** (a pointer to a pointer) but that would, in this case, make the code needlessly complex.
The leggif2 function has the same problem.
i keep getting a segmentation fault when running this program. I'm attempting to read the files (inserted into the command line), and allocate the x and y coordinates in each file to a dynamically allocated memory struct called POINTS (using the function called readPoints). After they have been saved into these structs, i then pass them to the function calls calc where the x and y values are multiplied, and then added onto the next x and y multiplied.. so on. Could someone please explain to me where i went wrong! I am not great at pointers.
Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
float xcord;
float ycord;
}POINTS;
int readPoints(char* file, int numofpoints);
int calc(POINTS* points, int numofpoints);
int main(int argc, char* argv[])
{
int numoffiles;
FILE* file;
int result, i;
numoffiles = argc;
POINTS* pointer;
int numofpoints;
if(numoffiles == 1)
{
printf("Please enter a file\n");
}
for(i=1; i<numoffiles; i++)
{
file = fopen(argv[i], "r");
fscanf(file, "%d", &numofpoints);
pointer = readPoints(file, numofpoints);
if( pointer == NULL)
{
printf("Error return from readPoints function");
}
result = calc(&pointer[i], numoffiles);
printf("%12f", result);
free(pointer);
}
}
int readPoints(char* file,int numofpoints)
{
int i, j;
POINTS* Pointstructs;
Pointstructs = (POINTS*)malloc((numofpoints)*sizeof(POINTS));
if(file == NULL)
{
printf("Error transferring file into readPoints\n");
}
for(i=0; i<numofpoints; i++)
{
fscanf(*file, "%f, %f", &Pointstructs[i].xcord, &Pointstructs[i].ycord);
printf("%f, %f", Pointstructs[i].xcord, Pointstructs[i].ycord);
}
return Pointstructs;
}
int calc(POINTS* points, int numofpoints)
{
int i=0, j=0;
int answer;
while(i<numofpoints && j<numofpoints)
{
answer += points[i].xcord * points[j].ycord;
i++;
j++;
}
return answer;
}
readpoints functions should take its first argument as file pointer BCS fopen returns FILE pointer but u are using char pointer. fscanf first argument should be a file pointer. Pls correct it
I have 2 lines (given below) in file data1.txt:
Da KOL -1.19503 5.27557163
MaB KOL -1.19503 5.27557163
I am not sure how I could extract specific words or numbers using fgets, hence I used fscanf to scan each component of the set and print them to another file. The code is:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
main()
{
FILE *fpt1, *fpt2;
fpt1=fopen("data1.txt","r");
fpt2=fopen("data2.txt","w");
int i;
double ep, si;
char *sto1, *sto2;
for(i=0;i<2;i++)
{
fscanf(fpt1,"%s\n",sto1);
fscanf(fpt1,"%s\n",sto2);
fscanf(fpt1,"%lf\n",&ep);
fscanf(fpt1,"%lf\n",&si);
fprintf(fpt2,"%s %s %2.8lf %2.8lf\n",sto1,sto2,ep,si);
}
fclose(fpt1);
fclose(fpt2);
}
But I am getting this output in file data2.txt:
Da (null) 0.00000000 0.00000000
KOL (null) -1.19503000 5.27557163
Although, the desired output is one with a single space in between each component of a line like:
Da KOL -1.19503 5.27557163
MaB KOL -1.19503 5.27557163
Can someone please help me fix this one?
#include <stdio.h>
//A good habit is not to use "main()"
int main(int argc, char *argv[])
{
FILE *fpt1, *fpt2;
fpt1=fopen("data1.txt","r");
fpt2=fopen("data2.txt","w");
int i;
double ep, si;
char sto1[100], sto2[100]; //here neeed array
for(i=0;i<2;i++)
{
fscanf(fpt1,"%s",sto1); //without '\n'
fscanf(fpt1,"%s",sto2);
fscanf(fpt1,"%lf",&ep);
fscanf(fpt1,"%lf",&si);
fprintf(fpt2,"%s %s %2.8lf %2.8lf\n",sto1,sto2,ep,si);
}
fclose(fpt1);
fclose(fpt2);
return 0;
}
The Idea which you have is correct but I have modified/corrected your code a bit. And I have used sscanf instead of fscanf. Here is the code,
#include<stdio.h>
#define MAX 256
int main(){
FILE *pfile1 =NULL,*pfile2 = NULL;
char *sto1=NULL,*sto2=NULL,line[MAX];
double ep,si;
pfile1 = fopen("dS.txt","r");
pfile2 = fopen("dR.txt","w");
if(pfile1 != NULL || pfile2 != NULL){
while(fgets(line,255,pfile1)!=NULL){
sscanf(line,"%s %s %Lf %Lf",&sto1,&sto2,&ep,&si);
fprintf(pfile2,"%s %s %2.5Lf %2.8Lf\n",&sto1,&sto2,ep,si);
}
fclose(pfile1);
fclose(pfile2);
}
return 0;
}
You used values of uninitialized variables having automatic storage duration sto1 and sto2 and invoked undefined behavior.
Assign pointers pointing to some valid buffer to them before using them.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE *fpt1, *fpt2;
fpt1=fopen("data1.txt","r");
fpt2=fopen("data2.txt","w");
int i;
double ep, si;
char *sto1, *sto2;
/* allocate enough size to store data */
sto1 = malloc(1000000);
sto2 = malloc(1000000);
for(i=0;i<2;i++)
{
fscanf(fpt1,"%s\n",sto1);
fscanf(fpt1,"%s\n",sto2);
fscanf(fpt1,"%lf\n",&ep);
fscanf(fpt1,"%lf\n",&si);
fprintf(fpt2,"%s %s %2.8lf %2.8lf\n",sto1,sto2,ep,si);
}
fclose(fpt1);
fclose(fpt2);
free(sto1);
free(sto2);
}
Adding error checking for fopen(), malloc() and fscanf() will make this code better.
Alternative way is to use statically allocated arrays instead of dynamically allocating buffer via memory management functions.
#include<stdio.h>
int main(void)
{
FILE *fpt1, *fpt2;
fpt1=fopen("data1.txt","r");
fpt2=fopen("data2.txt","w");
int i;
double ep, si;
char sto1[1000], sto2[1000]; /* allocating too big array as automatic local variable may cause stack overflow */
for(i=0;i<2;i++)
{
fscanf(fpt1,"%s\n",sto1);
fscanf(fpt1,"%s\n",sto2);
fscanf(fpt1,"%lf\n",&ep);
fscanf(fpt1,"%lf\n",&si);
fprintf(fpt2,"%s %s %2.8lf %2.8lf\n",sto1,sto2,ep,si);
}
fclose(fpt1);
fclose(fpt2);
}
You can use static arrays
At the moment the program is reading "unable to open the input file" which means the size is 0. I made the input file with my editor, but I'm not sure what the issue could be. Is there anything up with my code that could cause this? Or is it more likely I just messed up the input.txt file?
#include <stdio.h>
#include <stdlib.h>
int load_data(char* filename, int *x, float *y)
{
int i=0;
FILE* file=fopen(filename,"r");
if(file==NULL)
{
return 0;
}
int size;
fscanf(file, "%d", &size);
for(i=0;i<size;i++)
{
fscanf(file, "%d%f", &x, &y);
}
fclose(file);
return size;
}
void print_data(int *acn, float *amt, int size)
{
int i;
int *p;
for(i=0;i<size;i++)
{
printf("%-10d%-10f ", *(acn+i), *(amt+i));
}
}
int main(int argc, char** argv)
{
int size=0, *x;
char *filename;
float *y;
if(argc!=3)
{
printf("\nInsufficient arguments.\n");
return 0;
}
int n=atoi(argv[2]);
int *acn;
float *amt;
int *fp=malloc(sizeof(int)*n);
if(size==0)
{
printf("\nUnable to open the input file.\n");
return 0;
}
load_data(filename, x, y);
print_data(acn, amt, size);
free(fp);
return 0;
}
There are number of problems in you program -
You are name of file from commal line but you do not store it in char *filename; and in function int load_data(char* filename, int *x, float *y)
you are passing filename.But filename does not have the name of file in it stored.
fscanf(file, "%d%f", &x, &y); when you pass pointer in fscanf with %d you don't need & operator.Just this will do-
fscanf(file, "%d%f", x, y);
You need to allocate memory using malloc to x and y.
size in both functions are different as you declare it again in the function and in main.Thats why size is always 0 in int main.
void print_data in this function you are printing value of acn and amt but both the pointer are unintialized and you are printing it so it will give undefined behaviour.
Also you have pointers which are declared in your program but not used .
In following lines of code (which you have posted), the value of size variable is 0. The value has never been updated, before checking at line if(size==0). That is why this if check is returning true and printing "Unable to open the input file".
You may want to set the value of size variable before this if check.
int size=0, *x; //HERE YOU ARE WRITING "SIZE" VARIABLE
char *filename;
float *y;
if(argc!=3)
{
printf("\nInsufficient arguments.\n");
return 0;
}
int n=atoi(argv[2]);
int *acn;
float *amt;
int *fp=malloc(sizeof(int)*n);
if(size==0) //HERE YOU ARE READING/CHECKING "SIZE" VARIABLE. THERE IS NO CHECGE IN VARIABLE BEFORE THIS SO, VALUE IS STILL '0'
{
printf("\nUnable to open the input file.\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct account{
int accountId;
char *name;
double amount;
};
int main(int argc, char **argv)
{
FILE *file=fopen(argv[1],"r");
struct account *Ptr;
int i,j;
int size=0;
fscanf(file,"%d",&size);
if(size==0)
{
printf("Unable to open file");
return 0;
}
printf("%d",size);
Ptr=malloc(sizeof(struct account)*size);
for(i=0;i<size;i++)
{
fscanf(file,"%d%s%lf\n",&(Ptr+i)->accountId,(Ptr+i)->name,&(Ptr+i)->amount);
}
for(j=0;j<size;j++)
{
printf("%d%s%lf\n",((Ptr+j)->accountId),(Ptr+j)->name,((Ptr+j)->amount));
}
fclose(file);
free(Ptr);
return 0;
}
This is used to read in the input file
2
2 Harry 23.45
8 Sally 100.91
Somehow the code reads in the first 2 for size and the second 2 during the for loop but nothing else
Your code has undefined behavior, because you are reading data into an uninitialized pointer:
fscanf(file,"%d%s%lf\n",&(Ptr+i)->accountId,(Ptr+i)->name,&(Ptr+i)->amount);
// ^^^^
// This pointer is uninitialized ----------------------+
There are three ways to address this:
Make name an array, rather than a pointer, e.g. char name[MAX_NAME], or
Use malloc to allocate space to name before reading data into it.
Read into a temporary buffer, then malloc the exact number of chars.