TreyZept
TreyZept

Reputation: 11

How can i add a character after every word in a string?

So what i have is a string(str) that i get from fgets(str, x, stdin);. If i write for example "Hello World" i want to be able to add a character infront of each word in the string.

To get this "Hello? World?" as an example. I think i've made it alot harder for myself by trying to solve it this way:

add(char *s, char o, char c){
    int i, j = 0;
    for (i = 0; s[i] != '\0'; i++) {
        if (s[i] != o) {
            s[j] = s[i];
        }
        else {
            s[j] = c;
        }
        j++;
    }
}  

 add(str, ' ','?');
 printf("\n%s", str);

This will read out "Hello?World" without the spaces. Now the only way i see this working is if i move everything after the first "?" one to the right while also making the positon of the "W" to a space and a "?" at the end. But for much longer strings i can't see myself doing that.

Upvotes: 0

Views: 1840

Answers (4)

Jeremy Friesner
Jeremy Friesner

Reputation: 73061

Just for fun, here's my implementation. It modifies the string in-place and in O(n) time. It assumes that the char-buffer is large enough to hold the additional characters, so it's up to the calling code to ensure that.

#include <stdio.h>

void add(char *s, char o, char c)
{  
   int num_words = 0;
   char * p = s;
   while(*p) if (*p++ == o) num_words++;

   char * readFrom = p;
   char * writeTo  = p+num_words;
   char * nulByte  = writeTo;

   // Insert c-chars, iterating backwards to avoid overwriting chars we have yet to read
   while(readFrom >= s)
   {  
      *writeTo = *readFrom;
      if (*writeTo == o)
      {  
         --writeTo; 
         *writeTo = c;
      }
      writeTo--;
      readFrom--;
   }

   // If our string doesn't end in a 'c' char, append one
   if ((nulByte > s)&&(*(nulByte-1) != c))
   {  
      *nulByte++ = c;
      *nulByte = '\0';
   }
}

int main(int argc, char ** argv)
{
    char test_string[1000] = "Hello World";
    add(test_string, ' ','?');
    printf("%s\n", test_string);
    return 0;
}

The program's output is:

$ ./a.out 
Hello? World?

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84551

Knowing the amount of storage available when you reach a position where the new character will be inserted, you can check whether the new character will fit in the available storage, move from the current character through end-of-string to the right by one and insert the new character, e.g.

#include <stdio.h>
#include <string.h>

#define MAXC 1024

char *add (char *s, const char find, const char replace)
{
    char *p = s;        /* pointer to string */

    while (*p) {                                /* for each char */
        if (*p == find) {
            size_t remain = strlen (p);         /* get remaining length */
            if ((p - s + remain < MAXC - 1)) {  /* if space remains for char */
                memmove (p + 1, p, remain + 1); /* move chars to right by 1 */
                *p++ = replace;                 /* replace char, advance ptr */
            }
            else {  /* warn if string full */
                fputs ("error: replacement will exceed storage.\n", stderr);
                break;
            }
        }
        p++;    /* advance to next char */
    }

    return s;   /* return pointer to beginning of string */
}
...

(note: the string must be mutable, not a string-literal, and have additional storage for the inserted character. If you need to pass a string-literal or you have no additional storage in the current string, make a copy as shown by @Selbie in his answer)

Putting together a short example with a 1024-char buffer for storage, you can do something like:

#include <stdio.h>
#include <string.h>

#define MAXC 1024

char *add (char *s, const char find, const char replace)
{
    char *p = s;        /* pointer to string */

    while (*p) {                                /* for each char */
        if (*p == find) {
            size_t remain = strlen (p);         /* get remaining length */
            if ((p - s + remain < MAXC - 1)) {  /* if space remains for char */
                memmove (p + 1, p, remain + 1); /* move chars to right by 1 */
                *p++ = replace;                 /* replace char, advance ptr */
            }
            else {  /* warn if string full */
                fputs ("error: replacement will exceed storage.\n", stderr);
                break;
            }
        }
        p++;    /* advance to next char */
    }

    return s;   /* return pointer to beginning of string */
}

int main (void) {

    char buf[MAXC];

    if (!fgets (buf, MAXC, stdin))
        return 1;

    buf[strcspn(buf, "\n")] = 0;
    puts (add (buf, ' ', '?'));
}

Example Use/Output

$ ./bin/str_replace_c
Hello World?
Hello? World?

Look things over and let me know if you have questions.

Upvotes: 1

selbie
selbie

Reputation: 104514

You can't safely extend a string with more characters without insuring the buffer that holds the string is big enough. So let's devise a solution that counts how many additional characters are needed, allocate a buffer big enough to hold a string of that length, then do the copy loop. Then return the new string back to the caller.

char* add(const char* s, char o, char c)
{
   size_t len = strlen(s);
   const char* str = s;
   char* result = NULL;
   char* newstring = NULL;

   // count how many characters are needed for the new string
   while (*str)
   {
       len += (*str== o) ? 2 : 1;
       str++;
   }

   // allocate a result buffer big enough to hold the new string    
   result = malloc(len + 1); // +1 for null char

   // now copy the string and insert the "c" parameter whenever "o" is seen
   newstring = result;
   str = s;
   while (*str)
   {
       *newstring++ = *str;
       if (*str == o)
       {
           *newstring++ = c;                
       }
       str++;
  }
  *newString = '\0';

  return result;
}

Then your code to invoke is as follows:

char* newstring g= add(str, ' ','?');
printf("\n%s", newstring);
free(newstring);

Upvotes: 2

abelenky
abelenky

Reputation: 64682

#include <stdio.h>
#include <string.h>

int main(void) {
    char text[] = "Hello World";

    for(char* word = strtok(text, " .,?!"); word; word = strtok(NULL, " .,?!"))
        printf("%s? ", word);

    return 0;
}

Example Output

Success #stdin #stdout 0s 4228KB
Hello? World? 

IDEOne Link

Upvotes: 1

Related Questions