如何在字符串中的每个单词之后添加一个字符?

时间:2020-01-05 02:39:33

标签: c

所以我所拥有的是我从fgets(str,x,stdin);获得的字符串(str)。 如果我写例如“ Hello World”,我希望能够在字符串中每个单词的前面添加一个字符。

要获取此“ Hello?World?”举个例子。我认为通过尝试以这种方式解决它,我自己变得更加困难:

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);

这将读出没有空格的“ Hello?World”。现在,我看到此工作的唯一方法是将所有内容都移到第一个“?”之后一个同时向右移动,同时还将“ W”的位置设为空格和“?”在最后。但是对于更长的字符串,我看不到自己这样做。

4 个答案:

答案 0 :(得分:2)

如果不能确保容纳字符串的缓冲区足够大,就不能安全地扩展带有更多字符的字符串。因此,让我们设计一个解决方案,计算需要多少个额外的字符,分配一个足以容纳该长度字符串的缓冲区,然后执行复制循环。然后将新字符串返回给调用者。

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;
}

然后您要调用的代码如下:

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

答案 1 :(得分:1)

#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;
}

示例输出

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

IDEOne Link

答案 2 :(得分:1)

知道到达插入新字符的位置时可用的存储量,可以检查新字符是否适合可用的存储,从当前字符到字符串末尾移到右侧并插入新字符,例如

#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 */
}
...

注意:该字符串必须是可变的,而不是 string-literal ,并且必须为插入的字符提供额外的存储空间。如果需要传递 string-literal 或当前字符串中没有额外的存储空间,请按照@Selbie的回答进行复制)

将一个简短的示例与一个1024-char缓冲区进行存储,您可以执行以下操作:

#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, ' ', '?'));
}

使用/输出示例

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

仔细研究一下,如果您有任何疑问,请告诉我。

答案 3 :(得分:0)

只是为了好玩,这是我的实现。它在O(n)时间内就地修改字符串。它假定char缓冲区足够大,可以容纳其他字符,因此取决于调用代码来确保这一点。

#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;
}

程序的输出为:

$ ./a.out 
Hello? World?