command line arguments issues - c

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;
}

Related

Struct initialized in function loses values (although it's an array)

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.

Segmentation fault 11, issue using pointers and returning them

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

Combining two files of floats into a single file in C

My task is to read from two files both containing floats. Then I have to put them in a new file in an ascending order. The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int numLines(const char * fileName){
FILE *file=fopen(fileName,"r");
int lines=0;
char c;
while((c=fgetc(file))!=EOF){
if(c==10){
lines++;
}
}
fclose(file);
return lines;
}
float * fileToArray(const char * fileName){
FILE *file=fopen(fileName,"r");
int numOfLines= numLines(fileName);
float * arr= (float*)malloc(numOfLines*sizeof(float));
int i;
for(i=0;i<numOfLines;i++){
fscanf(file,"%f\n",&arr[i]);
}
fclose(file);
return arr;
}
int cmpfunc(const void *a, const void *b){
float fa= *(const float*) a;
float fb= *(const float*) b;
return (fa>fb)-(fa<fb);
}
int isSorted(FILE *fp){
float prev;
float o;
do{
fscanf(fp,"%f\n",&prev);
fscanf(fp,"%f\n",&o);
if(prev>o){
fclose(fp);
return 1;
}
}while(fscanf(fp,"%f\n",&o)==1);
fclose(fp);
return 0;
}
int main(int argc, const char * argv[]){
const char *fileName1;
const char *fileName2;
const char *fileOut;
FILE *fp1;
FILE *fp2;
FILE *fp3;
float *arr1;
float *arr2;
int size1;
int size2;
if(argc!=4){
printf("Usage: fileSort.exe FILENAME1 FILENAME2 FILEOUT");
return 0;
}
else{
fileName1= argv[1];
fileName2= argv[2];
fileOut= argv[3];
fp1= fopen(fileName1,"r");
fp2= fopen(fileName2, "r");
fp3= fopen(fileOut, "w");
if(fp1!=NULL && fp2!=NULL){
arr1=fileToArray(fileName1);
arr2=fileToArray(fileName2);
size1=sizeof(arr1)/sizeof(float);
size2=sizeof(arr2)/sizeof(float);
if(!isSorted(fp1) || !isSorted(fp2)){
printf("The files are not sorted in increasing order. Please sort them.");
}
else{
float * arr3= malloc((size1+size2)*sizeof(float));
int k;
memcpy(arr3,arr1,size1*sizeof(float));
memcpy(arr3+size1,arr2,size2*sizeof(float));
qsort(arr3,size1+size2,sizeof(float),cmpfunc);
for(k=0;k<(size1+size2);k++){
fprintf(fp3,"%f\n",arr3[k]);
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
else{
printf("Files could not be opened\n");
}
return EXIT_SUCCESS;
}
Two sample files for testing this code would be:
data1.txt:
0.586399
0.769484
0.864755
6.229683
data2.txt:
0.279828
0.309235
0.591884
0.962811
1.361349
10.203892
12.158343
The result should be their ordered combination. However, I get this as a result:
0.279828
0.309235
0.586399
0.769484
No matter what I change, it always writes four numbers into the resulting file. The helper functions seem to be doing their jobs just fine. It looks like the problem comes up when I'm trying to create the third array and fill it up (or at least I assume that's the source). I have no idea where this problem is coming from though. I would really appreciate some help on this issue.
The variable arr1 is not an array, it is a pointer to a float even though you are using it as pointer to the first float element in the array.
This means that sizeof will return to you the size of the pointer which is either 4 bytes or 8 bytes depending whether you are compiler 32-bit or 64-bit.
One way to fix this is to pull out the calculation of the number of lines like this:
int size1 = numLines(fileName1);
int size2 = numLines(fileName2);
arr1=fileToArray(fileName1, size1);
arr2=fileToArray(fileName2, size2);

Allocating memory for an array of struct i get an error

the code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
typedef struct word{
char word[20];
int occurrance;
} word;
int array_word_creator(word *array, FILE *fp);
void initialize(word array[], int max);
void comparator(word array[], int max, FILE *fp);
void printer(word array[], int max);
int main(int argc, char *argv[])
{
FILE *f_sent, *f_words;
word *array;
int arr_lenght=0;
if(argc!=3)
{
printf("Wrong argument number, please use NAME FILE1 FILE2;\n");
exit(EXIT_FAILURE);
}
if((f_sent=fopen(argv[1], "r"))==NULL||(f_words=fopen(argv[1], "r"))==NULL)
{
printf("Can't find or open the files, please check if the name is correct\n");
exit(EXIT_FAILURE);
}
arr_lenght=array_word_creator(array, f_words);
comparator(array, arr_lenght ,f_sent);
printer(array, arr_lenght);
return 0;
}
int array_word_creator(word *array, FILE *fp)
{
int n,i=0;
fscanf(fp,"%d",&n);
*array= malloc(n*sizeof(word));
while(fscanf(fp,"%s", array[i].word)!=EOF)
{
i++;
}
initialize(array,n);
return n;
}
void initialize(word array[], int max)
{
int i;
for(i=0;i<max;i++)
{
array[i].occurrance=0;
}
}
void comparator(word array[], int max, FILE *fp)
{
char word[MAX];
int i;
while(fscanf(fp,"%s", word)!=EOF)
{
for(i=0;i<max;i++)
{
if(strcmp(word, array[i].word)==0)
{
array[i].occurrance++;
}
}
}
}
void printer(word array[], int max)
{
int i;
for(i=0;i<max;i++)
{
if(array[i].occurrance>0)
{
printf("The word '%s' occurs %d times\n", array[i].word, array[i].occurrance);
}
}
}
And the compiler says me:
C:\Users\Matteo\Google Drive\Programming\C\lab3\es1\main.c|47|error: incompatible types when assigning to type 'word' from type 'void *'|
I just studied memory allocation so i'm having some trouble with it, especially with structures. If possible, plase link me also some good docs about this subject.
thank you!
In main word *array is a pointer to a structure of type word.
You then pass array, which does not point to anything, to the function array_word_creator.
You then try to assign the pointer returned by malloc to where array is pointing, but it doesn't point anywhere yet, and even if it did, it would be pointing to a word (since it is a word *), so it can't store a pointer, hence the compiler error.
If you want to set the array pointer in main to the result of malloc, you have to pass a pointer to the pointer. int array_word_creator(word **array, FILE *fp), then you would call it by doing array_word_creator(&array, .... ), the your *array = malloc will work.
You want this:
...
arr_lenght = array_word_creator(&array, f_words);
...
int array_word_creator(word **array, FILE *fp)
{
int n, i = 0;
fscanf(fp, "%d", &n);
*array = malloc(n * sizeof(word));
while (fscanf(fp, "%19s", (*array)[i].word) != EOF)
{
i++;
}
initialize(*array, n);
return n;
}

Segmenatation fault in fread

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.

Resources