1

I read the input file , which has 911 lines , and want to copy these 911 lines into the output file , after making a few changes to each line..

I am getting segmentation fault when i run this.. I dont know why.. can anyone please help..

#include<stdio.h>
void main()
{
    int i;
    FILE *fin,*fop;char* str;
    fin=fopen("atk561011.txt","r");
    if(fin=NULL) printf("ip err");
    fop=fopen("svmip.txt","w");
    if(fop=NULL) printf("op err");
    for(i=1;i<=911;i++)
    {
        fgets(str,150,fin);
        if((i>300&&i<=360)||(i>600&&i<=660)) 
            str[7]='1';
        else 
            str[7]='0';
        fputs(str+7,fop);
        putc('\n',fop);
    }
    fclose(fin);
    fclose(fop);
}
albertein
  • 26,396
  • 5
  • 54
  • 57
trinity
  • 10,394
  • 15
  • 49
  • 67
  • Thanks everyone , It is now working.. after making the 2 changes : allocating memory to str and correcting (fin==null).. – trinity Jan 19 '10 at 19:28

4 Answers4

4

For a start, this is wrong:

if(fin=NULL)

Should be:

if (fin == NULL)

(the same goes for fop, of course). And if you didn't succeed opening the file - don't just print an error, exit, because what are you going to read from? Keep in mind that the output of printf is buffered and in case of a segfault you won't always see it at all, even if it ran before the fault.

Another thing: you don't allocate memory for str, yet write into it with fgets.

And another thing: reading a pre-defined amount of lines from the file is probably a bad idea. It's better to read from the input until there is an end of file, or until a required amount of lines has been read.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
1

Your not allocating any space for the pointer str.

Change that to either char str[/*Max Length You expect 150? */] or allocate the buffer.

In the meantime your code is walking all over memory - thus the segmentation fault.

Ruddy
  • 1,734
  • 10
  • 11
1

Here's the corrected code that should do it.

#include
#define MAX_BUF   150
void main()
{
    int i;
    FILE *fin,*fop;char* str;
    str = malloc((MAX_BUF * sizeof(char)) + 1);
    if (str == NULL){
       printf("Out of memory\n");
       exit(-1);
    }
    fin=fopen("atk561011.txt","r");
    if(fin == NULL){
        printf("ip err");
        exit(-2);
    }
    fop=fopen("svmip.txt","w");
    if(fop == NULL){
        printf("op err");
        exit(-3);
    }
    for(i=1;i<=911;i++)
    {
        fgets(str,150,fin);
        if((i>300&&i<=360)||(i>600&&i<=660)) 
            str[7]='1';
        else 
            str[7]='0';
        fputs(str+7,fop); 
        // What is that for? should it be
        // fputs(str, fop); ????? 
        // since you're outputting the 7'th character (1/0)?
        putc('\n',fop);
    }
    fclose(fin);
    fclose(fop);
    if (str != NULL) free(str);
}

I have added logic checking to ensure if the file exists, to continue processing. Failure to do so will cause the code to blow up. Since in the original code, you were printing "ip err" if the input failed or in the case of output failure, yet continue on into the for loop which will render the execution to fail in that case as it would still be attempting to read from an non-existant file handle on failure.

Edit: Please see the comment above in the code. Are you trying to output 1/0's based on the conditional value of i between the ranges of 300-360 and 600-660 inclusively, into the output file. Can you clarify? Should that be

fputs(str[7], fop);

Hope this helps, Best regards, Tom.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • By the way, what is the purpose of str+7?? Have edited the code to highlight this. – t0mm13b Jan 19 '10 at 19:18
  • Thanks for that , now it is working.. I just wanted to automate this manual work i had to do now.. This code was not meant to solve any general problem.. < that str+7 is to avoid copying the first 7 chars > to the new file. – trinity Jan 19 '10 at 19:25
0

Both fin=NULL and fop=NULL should both be using the 'equal-equal' operator. You're setting fin and fop to NULL instead of checking for a bad return value.

Mark Pauley
  • 1,445
  • 12
  • 11