// code readability is every bit as important as the algorithm used
// when compiling, have all warnings enabled, and then fix them
// OP can add parameter checking and make the str1 and str1 be pointers
// with appropriate changes to the rest of the code
// I changed return types from void to int
// for set() and concat() so main could free the allocated memory areas
// the 'software contract' concept says the sub functions in the file
// do not need to check their parameters for validity
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strlen()
// strdup() should have been prototyped by string.h,
// but was not on my computer
char *strdup(const char *s);
// dont clutter the code with frivilous typedef's
struct string_t
{
int len;
char * s;
};
// prototypes
int concat (struct string_t*, struct string_t* );
int set( struct string_t*, char* );
int main(void)
{
//create variables
// your learning C, so keep it simple
struct string_t str1 = {0,NULL}; // good programming practice to initialize local variables
struct string_t str2 = {0,NULL};
if( !set( &str1, "hello " ) )
{
if( !set( &str2, "world!" ) )
{
printf("\nconcatenate str1 and str2\n");
if( !concat(&str1,&str2) )
{
printf("concatenation result is:\n");
printf("%p , %s",(void*)&(str1.s), str1.s);
printf("\n------End------\n");
} // end if
} // end if
} // end if
free(str1.s);
free(str2.s);
return EXIT_SUCCESS;
} // end function: main
// <-- pString1 must point to an instance of struct string_t
// do not free() the pNewString
// as it is a pointer to a literal,
// not a pointer to allocated memory
int set( struct string_t* pString1, char* pNewString ) // <-- use meaningful/descriptive names
{
int returnValue = 0; // indicate success
char * temp = strdup(pNewString);
if( NULL == temp )
{ // then strdup failed
perror( "strdup failed" );
returnValue = 1; // indicate failure
}
else
{ // else, strdup successful
pString1->s = temp;
pString1->len = strlen(pString1->s)+1;
}
return( returnValue );
} // end function: set
int concat (struct string_t* pString1, struct string_t* pString2)
{
int returnValue = 0; // indicate success
int totalLen = pString1->len + pString2->len + 1;
//printf( "\nbefore: string1->len =%i,string2->len=%d, totalLength=%i\n",
// pString1->len,
// pString2->len,
// totalLen);
//printf("\nbefore: string1:%s, string2:%s\n",
// pString1->s, pString2->s);
// <-- there is no room in string1->s for any more chars so:
char * temp;
if( NULL == (temp = realloc(pString1->s, totalLen) ) )
{ // then realloc failed
perror( "realloc failed" );
returnValue = 1; // indicate failure
}
else
{
free( pString1->s);
pString1->s = temp;
//printf("\n after realloc: str1.len:%i, strl.s:%s\n",
// pString1->len, pString1->s);
int i=0;
for(;i<totalLen;i++)
{
pString1->s[strlen(pString1->s)] = pString2->s[i];
pString1->s[strlen(pString1->s)] = '\0';
} // end for
pString1->len = totalLen;
pString1->s[totalLen] = '\0';
//printf("after: str1addr:%p , str1:%s\n",pString1->s,pString1->s);
//printf( "\nstring1->len =%i,string2->len=%d, totalLength=%i\n",
// pString1->len,
// pString2->len,
// totalLen);
} // end if
return( returnValue );
} // end function: concat