1827894 Members
1769 Online
109969 Solutions
New Discussion

Program C

 
SOLVED
Go to solution
Piotr Kirklewski
Super Advisor

Program C

Hi there
I want to read a csv file line by line.
The program compiles fine but when I'm trying to run it I get "segmentation fault". Could anyone help me to resolve that problem ?

#include
#include
main(){
char wildcard[10][2];
char *line = NULL;
FILE *file;
file = fopen("/robot/wildcard.csv","r+");

while (!feof(file)){
fscanf(file,"%s",line);
printf("%s\n",line);
}

}

root@robot:/robot# ./file
Segmentation fault

(gdb) run ./file.c
Starting program: /robot/file ./file.c

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7adbe52 in ?? () from /lib/libc.so.6
(gdb)

Jesus is the King
11 REPLIES 11
Dennis Handly
Acclaimed Contributor
Solution

Re: Program C

>char *line = NULL;
>fscanf(file,"%s",line);

You are trying to read into a NULL pointer. Also, if you are just reading buffers, you should use fgets(3)/fputs(3):
char buffer[4096];
while (fgets(buffer, sizeof(buffer), file)) {
fputs(buffer, stdout);
}

>0x00007ffff7adbe52 in ?? /lib/libc.so.6

This is NOT HP-UX. What OS version are you running?
Hein van den Heuvel
Honored Contributor

Re: Program C


You did not provide a buffer for fscanf

Instead of: char *line = NULL;
Try : char line[1000];

or use MALLOC : line = malloc ( 1000 );

The 1000 is arbitrary, pick what you need and CHECK... and check the malloc, and check the OPEN.

hth,

Hein
Hein van den Heuvel
Honored Contributor

Re: Program C

Oops, sorry for the duplicate reply. Walked away for while before hitting submit. Hein
Laurent Menase
Honored Contributor

Re: Program C

Piotr, Denis version is far better than using fscanf(), as it get the first line you can parse then.
( fscanf() don't allocate the "line" memory, so you need to allocate it like fgets)

so a char buff[8192];scanf(file,"%8192s",&buf) will give the first word ( separated by space) and not the first line, ( with a maximum size of 8192






Piotr Kirklewski
Super Advisor

Re: Program C

Ok
Thanks to your help I was able to resolve the segmentation error. Now I can't print the array.
Could you please help me to figure out why ?
Reagrds

FILE *fp;
char *StrArr[5];

fp = fopen("/robot/wildcard.csv", "r+");

int i;
for(i=0;i<=10;i++){
fscanf(fp, "%s\n", StrArr[i]);
}

int j;
for(j=0;j<=10;j++){
fprintf("%s\n",StrArr[j]);
}

root@robot:/robot# gcc -o x x.c
x.c: In function 'main':
x.c:34: warning: passing argument 1 of 'fprintf' from incompatible pointer type
/usr/include/stdio.h:353: note: expected 'struct FILE * __restrict__' but argument is of type 'char *'
x.c:34: warning: format not a string literal and no format arguments

Jesus is the King
Hein van den Heuvel
Honored Contributor

Re: Program C

Same error. Worse really.
You declared an array of 5 pointers to strings.
You allocated none of those strings and try yo use 10.
It seems you are not ready to tackle this job.
Please work with a peer to get up to speed.

And.... XML's have been parsed before. Find a package to do the job?

Or is this a training exercise perhpas?

Good luck with your homework,

Hein
Steven Schweda
Honored Contributor

Re: Program C

> x.c:34: warning: passing argument 1 of 'fprintf' from incompatible pointer type
> [...]

man printf
and/or:
man fprintf

Look for differences.

> It seems you are not ready to tackle this job.

He has a point. Trying to learn basic C
programming by asking questions like this
here is not an efficient use of anyone's
time.
Dennis Handly
Acclaimed Contributor

Re: Program C

>for(i=0;i<=10;i++){

The correct pattern is:
for (i=0; i < sizeof(StrArr)/sizeof(StrArr[0]); ++i){

This will do the number of elements in StrArr, not 11.

>fprintf("%s\n",StrArr[j]);

As Steven mentioned, you either use:
printf("%s\n", StrArr[j]);
fprintf(stdout, "%s\n", StrArr[j]);

Again, what version of Linux are you using?
Laurent Menase
Honored Contributor

Re: Program C


FILE *fp;
#define SIZEOFSTRARR 10
char *StrArr[SIZEOFSTRARR];
int i;
int j;

fp = fopen("/robot/wildcard.csv", "r+");

for(i=0;i<=SIZEOFSTRARR;i++){
StrArr[i]=malloc(8193);
fscanf(fp, "%8192s\n", StrArr[i]);
}

for(j=0;j<=SIZEOFSTRARR;j++){
fprintf("%s\n",StrArr[j]);
}

or

FILE *fp;
#define SIZEOFSTRARR 10
char StrArr[SIZEOFSTRARR][8193];/* don't fortget the ending 0*/
int i;
int j;

fp = fopen("/robot/wildcard.csv", "r+");

for(i=0;i<=SIZEOFSTRARR;i++){
fscanf(fp, "%8192s\n", StrArr[i]);
}

for(j=0;j<=SIZEOFSTRARR;j++){
fprintf("%s\n",StrArr[j]);
}


or

FILE *fp;
#define SIZEOFSTRARR 10
char *StrArr[SIZEOFSTRARR];
int i;
int j;

fp = fopen("/robot/wildcard.csv", "r+");

for(i=0;i<=SIZEOFSTRARR;i++){
StrArr[i]=malloc(8193);
fgets( StrArr[i],8193,fp);
}

for(j=0;j<=SIZEOFSTRARR;j++){
fprintf("%s\n",StrArr[j]);
}

In any case you need to allocate your buffer before passing it to *scanf/fgets
Also be sure to use %ns where n is the size of your buffer-1 too be sure you will not overrun your buffer


ie
#include
main()
{
char buf[1000];
scanf("%s",buf);
printf("%d",strlen(buf));
}
# cc t.c
# yes | tr "\012" ',' | dd bs=10000 count=1 | a.out
Memory fault
#include
main()
{
char buf[1000];
scanf("%999s\n",buf);
printf("%d",strlen(buf));
}
# cc t.c
# yes | tr "\012" ',' | dd bs=10000 count=1 | a.out
999
# echo 123456789 123456789 | a.out
9
--> it reads only the 1st word!

Dennis Handly
Acclaimed Contributor

Re: Program C

Laurent: for (i=0;i<=SIZEOFSTRARR;i++)

Ack! You have one too many. That's:
for (i=0; i < SIZEOFSTRARR; ++i)
Laurent Menase
Honored Contributor

Re: Program C

oops yes Denis you are right :D, I didn't see the <= in my copy past, since I don't use it usualy-