Thread: C programming Seg fault help

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    22

    C programming Seg fault help


    I'm making a line editor(for a file) & up tp append function.(type in "a")
    the append function is to append something after the current line.
    im now getting seg fault but cant really find out what cause the problem
    really frustrated
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define NUMBERLINES 1000  // max number of lines that can be read
    #define LINELENGTH  1000  // max length of a line
    #define FNAMELENGTH 100   // max length of a file name
    #define CMDLENGTH   102   // max length of a command (e.g.'f' + ' ' + filename)
    
    
    typedef struct Node {
         char   line[LINELENGTH];
         struct Node *next;
    } NodeT;
    
    
    NodeT* ScanInput(FILE *, char*, NodeT*);
    void PrintCommand(void);
    void PrintSpace(void);
    NodeT *PrintAll(NodeT *);
    NodeT *ReadFile(char *);
    void Unknown(void);
    void PrintCur(NodeT *);
    NodeT *makeNode(char *);
    NodeT *GotoB(NodeT* );
    NodeT *ReadFirst(FILE *);
    NodeT *DecP(NodeT *, char *);
    NodeT *IncP(NodeT *, char *);  
    NodeT *Append(char *,NodeT *);
    
    
    
    int main(int argc, char **argv) {
     
       FILE *fp;
       fp = NULL;
       char filename[FNAMELENGTH];
       NodeT *cur = NULL;  
    
       if(argc > 2){
          printf("Usage: ./led [filename]\n");
          exit(1);
       }
    
       if(argv != NULL){
          strcpy(filename,argv[1]);
          if((fp = fopen(filename,"r")) != NULL){
          printf("Existing file\n");      
          cur = ReadFirst(fp);
          fclose(fp);
          }
          
          else{
             fp = fopen(filename,"w");
             printf("Creating file %s\n", filename);
          }
       }
       while(1) cur = ScanInput(fp, filename, cur);
    
       return 0;
    
    }
    
    
    NodeT* ScanInput(FILE *s, char *argv, NodeT *cur){
       char input[CMDLENGTH];   
       char filename[FNAMELENGTH];
       NodeT *head = NULL;
       NodeT *tmp = NULL;
       char curline[LINELENGTH];
       FILE *fp;
       fp = NULL;
       
       
       strcpy(filename,argv);
       
    
       printf("? ");   
          
       fgets(input,CMDLENGTH,stdin);   
       if(strcmp(input,"h\n") == 0){
          PrintCommand();
       }
       if(strcmp(input,"q\n") == 0){
          exit(1);
       }
       if(strcmp(input,"p\n") == 0){
          
          head = ReadFile(filename);
          PrintAll(head);
          cur = GotoB(head);
          
       }
       if(strcmp(input,"x\n") == 0){
          printf("Forced exit, changes not saved\n");
          exit(1);
       }
       if(strcmp(input,".\n") == 0){
          PrintCur(cur);
       }
       if(strcmp(input,"-\n") == 0){
          cur = DecP(cur,filename);
          PrintCur(cur);
       }
       if((strcmp(input,"+\n") == 0) || (strcmp(input,"\n") == 0)){
          cur = IncP(cur,filename);
          PrintCur(cur);
       }      
    
       
       if(strcmp(input,"a\n") == 0){
          head = Append(filename,cur);
               
       }
    
    
    /*
       if(strcmp(input,"f") == 0){
          if(scanf("%s",filename) != 0) {
             Unknown();
          }
          if((fp1 = fopen(filename,"r")) != NULL){
             fclose(fp1);
             printf("File %s already exist, saving will overwrite", filename);
          }
          else {
             printf("Creating file :%s\n", filename);
             fp1 = fopen(filename,"w");
             
          }
       }*/
    
    
       return cur;
    
    }
    
    
    NodeT *ReadFirst(FILE *fp){
       NodeT *tmp;
    
       char line[LINELENGTH];
       
       if(fgets(line, LINELENGTH , fp) != NULL){
          tmp = makeNode(line);
       }
       return tmp;
    }
    
    
    
    NodeT *GotoB(NodeT* head){
       NodeT *tmp;
       tmp = head;
       if(tmp == NULL){
          return NULL;
       }
       while(tmp->next != NULL){
          tmp = tmp -> next;
       }
       
       return tmp;
    }
    
    void PrintCur(NodeT *cur){
       //if(cur == NULL) return ;
       
       printf("%s",cur->line);
    }
    
    
    
    
    void PrintCommand(){
       
       printf("Commands are (in upper or lower case):\n");
       PrintSpace();
       printf("q:      quit\n");
       PrintSpace();
       printf("s:      save\n");
       PrintSpace();
       printf("x:      force exit\n");
       PrintSpace();
       printf("f <filename>: the file is called <filename>\n");
       PrintSpace();
       printf("h:      print this help message\n");
       PrintSpace();
       printf("d:      delete current line\n");
       PrintSpace();
       printf("a:      append after current line, terminated by '.'\n");
       PrintSpace();
       printf("i:      insert before current line, terminated by '.'\n");
       PrintSpace();
       printf("p:      print all lines\n");
       PrintSpace();
       printf(".:      print current line\n");
       PrintSpace();
       printf("+:      increment line and print\n");   
       PrintSpace();
       printf("<return>:     same as '+'\n");
       PrintSpace();
       printf("-:      decrement line and print\n");
       PrintSpace();
       printf("number: make 'number' the current line\n");
    
    }
    
    void PrintSpace(){
       printf("        ");
    }
    void Unknown(){
       printf("Unknown command: ignoring\n");
    }
            
    NodeT *PrintAll (NodeT *s) {
       NodeT *cur;
       int line = 1;
       cur = s;
    
       if(strcmp(cur->line,"\n") == 0) {
          printf("Empty File\n");
          return NULL;
       }
    
       while(cur != NULL) {
        
          printf("LINE %d %s", line, cur->line);
          cur = cur->next;
          line++;
       }
       return cur;
    
    }
    
    NodeT *ReadFile(char *filename){
       int i = 0;   
       char line [LINELENGTH ];    
       char *get;
       FILE *fp;
       fp = NULL;
       
       NodeT *head;
       NodeT *cur;
       NodeT *new;
       
       if((fp = fopen(filename,"r")) == NULL){
          printf("Empty File\n");   
          printf("%s\n",filename);
          return NULL;
       }
       
       if((get = fgets(line, LINELENGTH , fp)) != NULL) {
          head = makeNode(line);
          cur = head;
          
       }
    
        
    
       while (fgets(line, LINELENGTH , fp) != NULL) {
          new = makeNode(line);
          cur->next = new;
          cur = new;
          i++;
       }
     
    
       fclose(fp);
       return head;
    }
    
    
    NodeT *Append(char *filename, NodeT *cur){
       FILE *fp;
       NodeT *head;
       NodeT *tmp;
       NodeT *inputhead;
       NodeT *inputcur;
       NodeT *inputnew;
       NodeT *tmp1;
       
       char line [LINELENGTH];
       char c;
    
       int i = 1,linenum = 1;
    
       head = ReadFile(filename);
       tmp = head;
       fgets(line,LINELENGTH, stdin);
       while(1){
          fgets(line,LINELENGTH, stdin);
          sscanf(line,"%c",&c);
          if(c == '.') break;
          if(i == 1){
             inputhead = makeNode(line);
             inputcur = inputhead;
             
          }
          else{
             inputnew = makeNode(line);
             inputcur->next = inputnew;
          }
          i++;
       }
    
       while(strcmp(tmp->line,cur->line) != 0 ){
          tmp = tmp->next;
       }
    
       cur = tmp->next;
    
       tmp->next = inputhead;
       inputcur->next = cur;
    
       fp = fopen(filename,"w+");
    
       tmp1 = head;
       while(tmp1 != NULL){
          fprintf(fp,"%s",tmp1->line);
          tmp1 = tmp1->next;
          linenum++;
       }
       
       return head;
    
    }    
    
    
    
    NodeT *makeNode(char *line) {
       NodeT *new;
       new = malloc(sizeof(NodeT));
       if (new == NULL) {
         
         exit(1); 
       }
       strcpy(new->line,line);
       new->next = NULL;
       return new;
    }
    
    NodeT *DecP(NodeT *cur, char *filename){
       NodeT *tmp;
       
          
    
       if((tmp = ReadFile(filename)) == NULL){
          printf("Empty File\n");
          return NULL;
       }
    
       while(strcmp(tmp->next->line,cur->line) != 0){
          tmp = tmp->next;
       }
    
       return tmp;
       
    }
    
    NodeT *IncP(NodeT *cur, char *filename){
       NodeT *tmp;
          
    
       if((tmp = ReadFile(filename)) == NULL){
          printf("Empty File\n");
          return NULL;
       }
    
       while(strcmp(tmp->line,cur->line) != 0){
          tmp = tmp->next;
       }
    
       if(tmp->next == NULL) return tmp;
       else return tmp->next;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You really need to start to learn how to use the debugger.

    Example session, going forwards.
    Code:
    $ gcc -Wall -std=c99 -g bar.c
    bar.c: In function ‘ScanInput’:
    bar.c:70: warning: unused variable ‘curline’
    bar.c:69: warning: unused variable ‘tmp’
    $ gdb ./a.out 
    GNU gdb (GDB) 7.1-ubuntu
    Copyright (C) 2010 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/sc/work/a.out...done.
    (gdb) run a1.txt
    Starting program: /home/sc/work/a.out a1.txt
    Existing file
    ? a
    ^C
    Program received signal SIGINT, Interrupt.
    0x0012d422 in __kernel_vsyscall ()
    (gdb) where
    #0  0x0012d422 in __kernel_vsyscall ()
    #1  0x001ebe03 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:82
    #2  0x0019542b in _IO_new_file_underflow (fp=0x284440) at fileops.c:606
    #3  0x00196ccb in _IO_default_uflow (fp=0x284440) at genops.c:440
    #4  0x001980f8 in *__GI___uflow (fp=0x284440) at genops.c:394
    #5  0x0018b28c in _IO_getline_info (fp=0x284440, buf=0xbfffeab4 "", n=999, delim=10, extract_delim=1, eof=0x0) at iogetline.c:74
    #6  0x0018b1d1 in _IO_getline (fp=0x284440, buf=0xbfffeab4 "", n=999, delim=10, extract_delim=1) at iogetline.c:42
    #7  0x0018a21a in _IO_fgets (buf=0xbfffeab4 "", n=1000, fp=0x284440) at iofgets.c:58
    #8  0x08048e48 in Append (filename=0xbffff338 "a1.txt", cur=0x804c170) at bar.c:289
    #9  0x080489fb in ScanInput (s=0x804c008, argv=0xbffff3d8 "a1.txt", cur=0x804c170) at bar.c:112
    #10 0x080487ac in main (argc=2, argv=0xbffff4f4) at bar.c:58
    (gdb) frame 8
    #8  0x08048e48 in Append (filename=0xbffff338 "a1.txt", cur=0x804c170) at bar.c:289
    289	   fgets(line,LINELENGTH, stdin);
    (gdb) list
    284	
    285	   int i = 1,linenum = 1;
    286	
    287	   head = ReadFile(filename);
    288	   tmp = head;
    289	   fgets(line,LINELENGTH, stdin);
    290	   while(1){
    291	      fgets(line,LINELENGTH, stdin);
    292	      sscanf(line,"%c",&c);
    293	      if(c == '.') break;
    (gdb) break 293
    Breakpoint 1 at 0x8048e88: file bar.c, line 293.
    (gdb) cont
    Continuing.
    hello
    
    
    Breakpoint 1, Append (filename=0xbffff338 "a1.txt", cur=0x804c170) at bar.c:293
    293	      if(c == '.') break;
    (gdb) print i
    $1 = 1
    (gdb) kill
    Kill the program being debugged? (y or n) y
    (gdb) quit
    Essentially, you set breakpoints at points of interest, you can then print variables (and change them), run the code or even single step it one line at a time.


    Or you can do the same thing going backwards; just run the code in the debugger, wait for the segfault, then use various commands to examine the program state. From there, think about how it got to that state and fix the code accordingly.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    22
    Yea I think learning how to use debugger is really important but I dont know how to install it into my computer(i have compiler though, call "cygwin")
    the only place i can use debugger is at school lab...do u have any link to download the debugger?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    cygwin is an environment to give a unix feel to windows.

    Run the cygwin setup utility, you should be able to see 'gdb' in the development tools section.
    You could even try 'ddd' (it gives you a more visual view, you can click on things to examine them and set breakpoints).
    Just list everything alphabetically if you still can't find it.

    I was once a big fan of cygwin, but I would generally suggest going the virtual machine route nowadays (both VmWare and Virtualbox offer excellent integrated solutions).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    22
    also i dont really understand the message from debugger ;(

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    22
    so what should i type in after compile?
    shouldn't it be gdb./mycode ?
    but command not found from cygwin

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Did you install gdb?
    And there is a space between 'gdb' and what you want to debug.

    > also i dont really understand the message from debugger ;(
    Well if you said which one, we might be able to help.

    You could also type 'help' at the debugger prompt - it has a lot of inline help, and there is a 500+ page manual as well.
    GDB Documentation

    It can do an awful lot of things, but you can do quite a bit of debugging using just the few commands I've shown already.
    Like anything else, it's a practised skill.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    22
    hmm thx a lot ~but still i wanna learn how to use debugger properly i think i didn't install it, i thought it was within cygwin

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by vince3214 View Post
    hmm thx a lot ~but still i wanna learn how to use debugger properly i think i didn't install it, i thought it was within cygwin
    Is there some specific reason you are using cygwin?

    I ask because it creates a somewhat weird programming scenario giving a "*nix flavour to Windows"... there are several compilers that will work on a pure windows environment and, as a rule, they render smaller, faster and more stable code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C programming Seg fault help
    By vince3214 in forum C Programming
    Replies: 12
    Last Post: 05-09-2011, 03:37 PM
  2. New to programming, Segmentation Fault?
    By dc210 in forum C Programming
    Replies: 3
    Last Post: 09-14-2010, 12:05 AM
  3. Replies: 4
    Last Post: 04-20-2010, 10:55 PM
  4. Replies: 5
    Last Post: 10-14-2009, 05:47 AM
  5. C Programming question (segmentation fault)
    By trustno1fox in forum C Programming
    Replies: 2
    Last Post: 05-01-2009, 04:55 PM