3

While this code is hideous and I've clearly solved the problem incorrectly, the code works (for the moment). I want to mess around with it, but I truly don't know what I'm doing wrong here. The goal is to, without using any built in functions, take the string "This is a test" and replace the "te" with "gho" to spell out "This is a ghost".

int main(int argc, const char * argv[]) {

    char *s = "This is a test";
    char *newstring = malloc(strlen(s));


    for (int i = 0 ; s[i] != '\0' ; i++){
        if (s[i] == 't' && s[i+1] == 'e') {
            newstring[i] = 'g';}
        else if (s[i] == 'e' && s[i+1] == 's') {
            newstring[i] = 'h';}
        else if (s[i] == 's' && s[i+1] == 't') {
            newstring[i] = 'o';
        }
        else if (s[i] == 't') {
            newstring[i] = 's';
        }
        else {
            newstring[i] = s[i];
        }
        }
    printf("%st",newstring);


    return 0;
}

My problem is that I don't know how to append characters to a new string in C so that I can maintain the integrity of the original string while just replacing single characters.

9
  • What is your question? Is it "how to append characters to a new string in C"? Commented May 7, 2015 at 22:09
  • 1
    @user3121023 this is true, I've adjusted it in my code. In my print statement, I have to manually add a "t" at the end; what can I do to avoid having to do that? I tried adding code under the last else if statement to say that, in addition to newstring[i] = 's'; newstring[i+1] = 't'. That didn't work. Commented May 7, 2015 at 22:14
  • 2
    I would split this into three functions: "find "te" in a string", "write "gho" at a position in a string" and "copy part of one string over the other. By splitting it, I bet the complexity falls right off. Commented May 7, 2015 at 22:20
  • @MooingDuck sounds like a good way to tackle it. My problem is that I'm completely new to C and have no clue how to implement this! With regards to 'copying' part of one string to another, I did that above by setting the index values to each other. Not sure how to search for multiple characters in a string AND note which indices they exist at. I could basically say "take the part of string leading up to 'te' and copy to new string". Then, "ignore 'te' and insert 'gho'". Then, "copy everything after 'te' to the new string". It's just actually implementing it... Commented May 7, 2015 at 22:25
  • 1
    you state that the code cannot use any of the system functions, but the posted code uses strlen(), malloc(), and printf() BTW: C does not have any builtin ability to perform any I/O. That is why libraries like stdio.h and stdlib.h are almost always needed. C does not have any builtin abillity to perform any string operations. That is why libraries like string.h are almost always needed. Commented May 7, 2015 at 22:55

3 Answers 3

2
char *s = "This is a test";
int len = 0;

while(s[len++]);//strlen(s) + 1
for (int i = 0 ; s[i] != '\0' ; i++){
    if (s[i] == 't' && s[i+1] == 'e') {//count "te"
        ++len;
        ++i;
    }
}

char *newstring = malloc(len);
int j = 0;
for (int i = 0 ; s[i] != '\0' ; i++){
    if (s[i] == 't' && s[i+1] == 'e') {
        newstring[j++] = 'g';
        newstring[j++] = 'h';
        newstring[j++] = 'o';
        ++i;
    } else {
        newstring[j++] = s[i];
    }
}
newstring[j] = '\0';
puts(newstring);
free(newstring);
Sign up to request clarification or add additional context in comments.

5 Comments

per the OP, cannot use 'built in' functions (those from a library) so no malloc() and no free() allowed. How the OP is expected to display anything to the user is a bit of a question because 'puts()' is one of those 'built in' functions from a library.
@user3629249 OP used malloc. also can use VLA.
I think the OP might have not fully understood the limitations given to them. In any case, an array can be defined on-the-fly after calculating how many bytes is needed.
I think I'm ok to use malloc, I don't really understand the concept of "free". I think I need to read up on pointers a bit more.
@karansatia it is not pointers per se, but blocks of memory you create with malloc or calloc, that you are then responsible to free when you are done using the memory. The only place pointers come into play is that both malloc and calloc return the start address to the newly created block of memory. Memory addresses are stored in pointers. (e.g. int *array = malloc (20 * sizeof (int)); creates a block of memory to hold 20 integers with the starting address to that block stored in array). When done with array, you must free (array); To return the memory to the system.
1

We should recognize a pattern in what you want to do. For a start, it's a useful trick to remember that you can fill out a new array like so:

int num = 0;
int buf[256];

buf[num++] = 123;
buf[num++] = 456;
buf[num++] = 789;

This is a shorthand. The line:

buf[num++] = 123;

Provides equivalent behavior to:

buf[num] = 123;
++num;

So what do we want to do here? We want to make a new string which is the same as the original except that it replaces "te" with "gho". So how about this?

#include <stdio.h>

int main(int argc, const char * argv[]) 
{
    const char *s = "This is a test";
    int i = 0;
    int new_len = 0;

    // We don't know what the final size of the string will be, so
    // let's make one that's generally large enough. Can do more
    // elaborate things here if you want a really robust solution.
    char new_string[256] = {0};

    // For each character in the string:
    for (i=0; s[i] != '\0'; ++i)
    {
        if (s[i] == 't' && s[i+1] == 'e')
        {
            // If we find "te", add "gho".
            new_string[new_len++] = 'g';
            new_string[new_len++] = 'h';
            new_string[new_len++] = 'o';

            // ... and skip one character to ignore both the 't' and the 'e'.
            ++i;
        }
        else
        {
            // Otherwise just add the same character.
            new_string[new_len++] = s[i];
        }
    }

    // Add the null terminator at the end of our new string.
    new_string[new_len] = '\0';

    // Output the new string.
    printf("%s\n", new_string);
}

19 Comments

Great effort ike, but you should revisit the part of the question that says without using any built in functions (emphasis in original). I bet you can do it.
sorry, per the OP, cannot use 'built in' functions I.E. those functions supplied by a library. so no 'string.h' allowed
Doh. I missed that part. I'm hoping printf is at least allowed.
hello all! I'm allowed to use printf!
Nice solution @Ike. Quick question: When you increment [new_len++], what does skipping the next character do? Let's say the indices that we find "te" at (in the original string) to be 4 and 5. That means that at indices 4, 5, and 6 in new_string, we have g, h, and o filled in respectively. What does skipping over index '6' in the original string do? Don't we just need to go to the very next two indices and add them (s and t)? Why do we need to skip the 6th index (not actually the 6th index, just in my bad example).
|
0
int myStrLen( char * );


int myStrlen( char *testStr )
{
    int rtnCount;

    for( rtnCount = 0; testStr[rtnCount]; rtnCount++ ) {;}

    return( rtnCount );
} // end function: myStrlen

other string functions can be implemented in a similar manner.

then the 'home grown' string functions could be used similar to this:

// get length of original string
int oldStringLen = myStrLen( s );

// provide room on the stack for the new string
char newString[oldStringLen+2] = {'\0'};

// search for occurrence of string to be replaced
char * targetString = myStrStr( s, "test" );
if( NULL == targetString )
{ // then target string not found
    // handle error??
    return( -1 );
}

// implied else, target string found in 's'

// copy first part of original string
myStrNCpy( newString, s, (targetString - s) +1 );

// append the replacement string
myStrCat( newString, "ghost" );

// append remainder of original string
myStrCat( newString, &targetString[4] );

does the code need to keep looking in the original string for other possible replacements?

of course, how to display the result to the user may be 'interesting' since C has no ability to perform any I/O without using something like the stdio.h library

1 Comment

char newString[oldStringLen+2] = {'\0'}; invalid syntax. variable-sized object may not be initialized

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.