#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    16
    Rep Power
    0

    Smile Segmentation Fault with Text Formatter - Help Please


    Hi, I am trying to create a text formatter in C, all I have here is:
    1. Stripping all leading space from input
    2. (Attempt at) Indenting all input by 4 spaces

    But I keep getting a segmentation fault - the problem is in the indent function, as the space remover works fine.
    Could someone please take a look and try and tel me what is wrong please? :)
    One note, the string should always end in '\0' - or NULL character

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char* argv[])
    {
        FILE *input_file = fopen(argv[1],"r");
        FILE *output_file = fopen("output.c","w");
    
        char line[200];
        char fmtline[200];
        int a, b, followingIndent, temp;
        followingIndent = 0;
    
        if(input_file == NULL)
        {
            printf("Cannot open file\n");
            exit(EXIT_FAILURE);
        }
    
        do
        {
        a = 0;
        b = 0;
        fgets(line, 200, input_file);
    
        RemoveWhiteSpace(&line, &fmtline);
        IncreaseIndent(&fmtline);
    
        fputs(fmtline,output_file);
    
        }while(feof(input_file) == 0);
    
        fclose(input_file);
        fclose(output_file);
    }
    
    void RemoveWhiteSpace(char *line, char *fmtline)
    {
        int a = 0;
        int b = 0;
    
        while(line[a] != '\0')
            {
                if(line[a] == ' ')
                {
                    a++;
                }
                else
                {
                    while(line[a] != '\0')
                    {
                        fmtline[b] = line[a];
                        a++;
                        b++;
                    }
                    fmtline[b] = '\0';
                }
            }
    }
    
    void IncreaseIndent(char *fmtline)
    {
        int a = 0;
        int b = 0;
        int i = 0;
        char cmparray[200];
    
        for(i=0; i<4; i++)
        {
            cmparray[i] = ' ';
        }
        i++;
    
        while(fmtline[a] != '\0')
        {
            cmparray[i] = fmtline[a];
            i++;
            a++;
        }
    
        a = 0;
        while(cmparray != '\0')
        {
            fmtline[a] = cmparray[b];
            a++;
            b++;
        }
        fmtline[a] = '\0';
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,086
    Rep Power
    2222
    Why are you ignoring the warnings?

    C:\otros\dcw>gcc -Wall 06s_01.c
    06s_01.c: In function `main':
    06s_01.c:27: warning: implicit declaration of function `RemoveWhiteSpace'
    06s_01.c:28: warning: implicit declaration of function `IncreaseIndent'
    06s_01.c:12: warning: unused variable `temp'
    06s_01.c:36: warning: control reaches end of non-void function
    06s_01.c: At top level:
    06s_01.c:39: warning: type mismatch with previous implicit declaration
    06s_01.c:27: warning: previous implicit declaration of `RemoveWhiteSpace'
    06s_01.c:39: warning: `RemoveWhiteSpace' was previously implicitly declared to return `int'
    06s_01.c:63: warning: type mismatch with previous implicit declaration
    06s_01.c:28: warning: previous implicit declaration of `IncreaseIndent'
    06s_01.c:63: warning: `IncreaseIndent' was previously implicitly declared to return `int'

    C:\otros\dcw>
    Does the problem remain when you correct those warnings? HINT: always declare or prototype your functions before you call them.
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,086
    Rep Power
    2222
    I just prototyped your functions and recompiled:
    C:\otros\dcw>gcc -Wall 06s_01.c
    06s_01.c: In function `main':
    06s_01.c:30: warning: passing arg 1 of `RemoveWhiteSpace' from incompatible pointer type
    06s_01.c:30: warning: passing arg 2 of `RemoveWhiteSpace' from incompatible pointer type
    06s_01.c:31: warning: passing arg 1 of `IncreaseIndent' from incompatible pointer type
    06s_01.c:15: warning: unused variable `temp'
    06s_01.c:39: warning: control reaches end of non-void function

    C:\otros\dcw>
    Here are Lines 30 and 31:
    Code:
        RemoveWhiteSpace(&line, &fmtline);
        IncreaseIndent(&fmtline);
    By the declaration of both functions, they are expecting you to pass a char* (ie, a char pointer). Instead, you are passing a char** (ie, a pointer to a char pointer) to them, just as the warnings are telling you! (so why are you ignoring the warnings?) Since line and fmtline are both char arrays, then by definition they are already char pointers. So why are you adding that extra level of indirection there?

    The warnings pointed us directly to the problem lines and also identified the problem. Warnings are much more important than error messages. Never ignore warnings!
    Last edited by dwise1_aol; January 11th, 2014 at 06:24 PM.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    16
    Rep Power
    0
    Originally Posted by dwise1_aol
    I just prototyped your functions and recompiled:

    Here are Lines 30 and 31:
    Code:
        RemoveWhiteSpace(&line, &fmtline);
        IncreaseIndent(&fmtline);
    By the declaration of both functions, they are expecting you to pass a char* (ie, a char pointer). Instead, you are passing a char** (ie, a pointer to a char pointer) to them, just as the warnings are telling you! (so why are you ignoring the warnings?) Since line and fmtline are both char arrays, then by definition they are already char pointers. So why are you adding that extra level of indirection there?

    The warnings pointed us directly to the problem lines and also identified the problem. Warnings are much more important than error messages. Never ignore warnings!
    ok thanks for the help. I ignored the warnings because the program ran fine without changing anything (with just the remove white space function) - I am relatively new at coding so dont tear me a new one

    But just to clarify , how exactly should I pass the char array into the functions? as I still get some warnings.

    I know the function receives them like:
    Function(char *chararray) - but how should I call the function?

    Thanks again for the help.
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    char line[200];

    line is a pointer to character.
    It's a constant pointer to character.

    So if you need to pass a character to pointer, the start of array line to function(char*);

    You can do any of these, all the same.
    Code:
    function(&line[0]);  /* address of character at start of array */
    function(line + 0);  /* offset 0 from the start of the array */
    function(0 + line);  /* because addition commutes.  This form is used in c puzzles */
    function(line); /* because 0 is the additive identity element */
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    16
    Rep Power
    0
    Originally Posted by b49P23TIvg
    char line[200];

    line is a pointer to character.
    It's a constant pointer to character.

    So if you need to pass a character to pointer, the start of array line to function(char*);

    You can do any of these, all the same.
    Code:
    function(&line[0]);  /* address of character at start of array */
    function(line + 0);  /* offset 0 from the start of the array */
    function(0 + line);  /* because addition commutes.  This form is used in c puzzles */
    function(line); /* because 0 is the additive identity element */
    Ah ok, thanks very much for the clarification.

    And just in case anyone is bothered, the cause of the segmentation fault was not the warnings, but instead writing:

    Code:
    while(fmtline != '\0')....
    // instead of
    while(fmtline[b] != '\0')...
    gratitude again to you clever people
  12. #7
  13. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    By ignoring compiler warnings your program will one day start WWIII. You will make a program that runs. You will not know what that program does.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo