erikbstack
erikbstack

Reputation: 13254

get string-parsing loop to work

I am working on my first C program, which needs to construct and deconstruct strings as it pleases. I don't know how to do that correctly, though. Could someone please explain?

Here's my code as far as I get it:

int main( int argc, char ** argv ) 
{ 
    if ( argc != 2 ) 
    { 
        _print_help(); /* defined above main() */ 
        exit(0); 
    } 

    char *s = argv[1]; 
    char *val = ""; 
    register int i; /* no idea why I need "register" and not just int */
    for(i=0;s[i];++i) /* loop over the string, take each character 
    {                    and add it to another string */
        strcat(val,s[i]); 
        printf("v:%s;\n",val); 
    } 
    printf("expression: %s\n",s); 
}

gcc is called from a make file (generated with autotools):

gcc -DHAVE_CONFIG_H -I.     -g -O2 -MT c-calc.o -MD -MP -MF .deps/c-calc.Tpo -c -o c-calc.o c-calc.c

And now it throws warnings that I shouldn't put an integer as second input to strcat and also that string3.h expects const char * __restrict__ and not just a char (I have to translate them because my Ubuntu talks to me in German). Activating my compiled program throws an Memoryaccess error and then the program returns with code 139 which seems to mean Segmentatation violation.

Upvotes: 0

Views: 299

Answers (1)

Kamran Amini
Kamran Amini

Reputation: 1062

Very good for the first program ;) First I write a program which does what you want, then I'll explain it a bit more.

int main( int argc, char ** argv ) 
{ 
    if ( argc != 2 ) 
    { 
        _print_help(); /* defined above main() */ 
        exit(0); 
    } 

    char *first_arg = argv[ 1 ] ;
    char val[ 1024 ]; //You should make enough memory to hold all the strings concatenated to each other. Here we suppose that 1024 is enough.

    strcpy( val , "" ) ; //Since val is an accumulator it should be initialized first.

    for( int i = 0 ; i < strlen( first_arg ) ; i++ ) /* loop over the string, take each character and add it to another string */
    {
        char char_str[ 2 ] ;
        char_str[ 0 ] = first_arg[ i ] ;
        char_str[ 1 ] = '\0' ;

        strcat( val , char_str ) ; 
        printf( "v:%s;\n" , val ) ; 
    }

    printf( "expression: %s\n" , val ) ; 
}

OK let's explain things better. First of all, you should know what a pointer is. A pointer is just a number which points to a place in the memory (usually heap memory). When you define char *val it is nothing more than a pointer and there is nothing allocated behind it. You have to use following commands to initialize it.

char val[ 1024 ] ;
char *val = new char[ 1024 ] ;

These commands are different. Actually the first command allocates the required memory( 1024 bytes) from the stack. But the former gets 1024 bytes from the heap memory. Former does not need to get freed because when you leave its containing block, it'll get freed. But the second command needs to get released manually by the programmer using this command :

delete [] val ;

About these lines :

char char_str[ 2 ] ;
char_str[ 0 ] = first_arg[ i ] ;
char_str[ 1 ] = '\0' ;

first_arg is a pointer which points to argv[ 1 ], this means they hold the same address. Characters are different from strings in C/C++. 'A' is different from "A". All strings in C/C++ should end with '\0' character. "A" can be seen as a string with 2 characters which the first is 'A' and the second one is '\0'. As well strcat() method always concatenate 2 strings so I had to build an string. A character with 2 cells which the first if my desired character and the next is a '\0' character. Now I can use this string to add it to val.

Upvotes: 3

Related Questions