每隔第N个字插入一个字符串

时间:2016-07-12 20:30:26

标签: c string word between

在每个第N个字符串之间添加字符串。

我的想法:

char *a = "one", *b = "two";

char *word = "Simple sentence containing some random words";
char result[200];


int len = strlen(word);
int spaces = 0;


for(int i = 0; i < len; i++)
{
    if(word[i] == ' ')
        spaces++;

    result[i] = word[i];

    if(spaces % 3 == 0)
    {
        //copy a to result
    }

    if(spaces % 4 == 0)
    {
        //copy b to result
    }

}

所以在我们准备好之后,结果将如下所示:

Simple sentence containing one some two random words

我已经尝试过strcpy,strcat和我已经挣扎了好几天但是我真的似乎没有得到这里的逻辑。怎么办?

2 个答案:

答案 0 :(得分:0)

好的,这就是我想出来的。我所做的一切的详细描述都在代码的注释中提供。

<强>代码:

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

#define MAX_OUTPUT_LENGTH 200

int main(int argc, char const *argv[]) {
  /* You can replace the words defined below ("one" and "two") with any words
  * you want to insert at the given positions.
  */
  char one[] = "one";
  char two[] = "two";

  char sentence[] = "Longer but still simple sentence containing even more words";
  char result[MAX_OUTPUT_LENGTH];


  int len = strlen(sentence);
  int spaces = 0;
  int k = 0; //See Weather Vane's comment for why you also need the variable k
  int skipUntilAnotherSpace = 0;

  for(int i = 0; i < len; i++)
  {
      if(sentence[i] == ' ') {
        spaces++;
        skipUntilAnotherSpace = 0; //See my explanation below for why this is done.
      }

      if (k == 0) {
        result[i] = sentence[i]; //Normally, we can use the variable "i" until our insertion
      } else {
        /* As Weather Vane's comment shows, after one insertion the positions you
        * need to grab from and insert to will change.  You cannot continue
        * to use "i". After the first insertion:
        * Sentence:
        * Simple sentence containing some random words
        *                            ^ position 27
        * Current value in result variable:
        * Simple sentence containing one [you want to insert here]
        *                                ^ position 31
        * So, we will need to insert into result at position k, and grab the info
        * from a different variable "i".
        */
        result[k] = sentence[i];
        //Increment k since it will not be incremented regularly in the for loop
        k++;
      }
      if((spaces % 3 == 0) && spaces != 0 && skipUntilAnotherSpace == 0)
      {
           int useVariableK = 0;
           if (spaces > 3) {
              /* Since spaces must already have been == 4, we have switched over
              to using variable K, so we must continue to do so */
              useVariableK = 1;
           }

           if(!useVariableK) {
           result[i] = ' '; //Add a space before we add the word "one"
           i++; //Increment i since we added the spaces

           int j;
           for (j = 0; j < strlen(one); j++) { //Add the word "one"
             result[i + j] = one[j];
           }
           //Increment the variable i the correct # of times since we added the word "one":
           i += (strlen (one));

           //Add a space after the word "one":
           result[i] = ' ';
           k = i + 1; //Set k = to i + 1 to account for the space we just added

           /* We need to revert back to where the variable "i" was before adding "one":

            We used the variable i to temporarily store the positions
            as we traversed across and added the word "one".  Then, we
            moved i back to the original position so we could access
            the correct position when using sentence[i] in the next iteration.

            Note that we need the +1 in the line below because we actually
            need to go back one more position than nessesary; when we re-enter
            the loop it will increment i to be +1 again! (sneaky)
           */
           i -= (strlen (one) + 1);

           /* Why we need the skipUntilAnotherSpace variable:
           We cannot simply increment the "spaces" variable after this; we need
           the number of spaces to conform to the number in the sentence, and
           just because we have more spaces in the result, it woudn't make sense
           to increment it for the sentence.

           However, if we leave it the same, then the next time we will enter
           this loop again since spaces == 3, and we don't want to enter this loop again;
           we have done our job already!

           So, we make sure not to enter the loop by setting the below variable
           to 1.  We do not enter the loop unless skipUntilAnotherSpace == 1.
           (If we even tried to increment the spaces variable, we would actually
            end up going into the next loop because spaces would = 4 ;) )

            Finally, we switch back skipUntilAnotherSpace to be 0 once
            another space is detected in the sentence.
           */
           skipUntilAnotherSpace = 1;
         } else {
           //Use variable K like we do if spaces == 4:
           /* Most of this loop is exactly identical to the previous one, except
           that we don't need another space since it was already added before when
           "one" was inserted, and we use the variable "k" instead of i. */
           int j;
           for (j = 0; j < strlen(one); j++) {
             result[k + j] = one[j];
           }
           k += (strlen (one));
           result[k] = ' ';
           k += 1;

           //spaces++;
           skipUntilAnotherSpace = 1;
         }
      }

      if((spaces % 4 == 0) && spaces != 0 && skipUntilAnotherSpace == 0)
      {
         /* Most of this loop is exactly identical to the previous one, except
         that we don't need another space since it was already added before when
         "one" was inserted, and we use the variable "k" instead of i. */
         int j;
         for (j = 0; j < strlen(two); j++) {
           result[k + j] = two[j];
         }
         k += (strlen (two));
         result[k] = ' ';
         k += 1;

         //spaces++;
         skipUntilAnotherSpace = 1;
      }

  }

  printf("%s.\n", result);
  return 0;
}

注意:请参阅Weather Vane's对此问题的评论,以进一步了解为什么变量k是必要的(我也在评论中对此进行了解释,我只是认为天气风向标版本更简洁一点。)

此代码生成的输出是:

Longer but still one simple two sentence containing one even more two words.

如果您已将变量onetwo分别更改为值“hello”“goodbye”,则代码仍会功能和产品:

Longer but still hello simple goodbye sentence containing hello even more goodbye words.

基本上,代码每隔三个单词在变量one[]中插入值,在句子中每四个单词插入变量two[]中的值。

我希望这有帮助!

答案 1 :(得分:0)

按字符串逐个字符并计算空格(只要你聚合空格等)没有任何问题,但是,还有另一种方法可以考虑更灵活一点。您可以使用strtok(在string.h中)标记化输入字符串,而不是搜索空格。然后,只需计算令牌(单词)并将您的添加内容作为 nth 单词(或单词)插入适当的位置(索引)。

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

enum { MAXC = 512 };

int main (void) {

    char *w1 = "one", *w2 = "two";              /* replacement words   */
    int nth1 = 3, nth2 = 4;                     /* positions for w1/w2 */
    char line[MAXC] = "", *p = NULL, *delim = " \t.,;\n";
    char *fmt1 = "%s", *fmt2 = " %s";

    while (fgets (line, MAXC, stdin)) { /* for each line read from stdin */
        int idx = 0;                        /* tokenize line with strtok */
        for (p = strtok (line, delim); p; p = strtok (NULL, delim)) {
            printf (!idx ? fmt1 : fmt2, p); idx++;    /* print token */
            if (idx == nth1) printf (fmt2, w1);   /* check and insert w1 */
            if (idx == nth2) printf (fmt2, w2);   /* and w2 in nth pos   */
        }
        putchar ('\n');
    }

    return 0;
}

注意:您可以根据需要定制索引。例如,您可以在插入第n个字后增加索引idx以使其插入按顺序等...)

示例使用/输出

$ echo "Simple sentence containing some random words" | ./bin/replacenthword
Simple sentence containing one some two random words

由于您没有对要操作的字符串进行硬编码,因此现在可以在整个文件中替换发送它的任何行中的 nth1 nth2 字。比如,

示例输入文件

$ cat dat/replcmt.txt
Simple sentence containing some random words
A quick brown fox jumps over the lazy dog
Fewer words
That's all folks

示例使用/输出w /文件

$ ./bin/replacenthword <dat/replcmt.txt
Simple sentence containing one some two random words
A quick brown one fox two jumps over the lazy dog
Fewer words
That's all folks one

如果您只想插入第n个单词,如果有以下单词,那么您所需要做的就是更改每个标记的测试和打印顺序。

    while (fgets (line, MAXC, stdin)) { /* for each line read from stdin */
        int idx = 0;                        /* tokenize line with strtok */
        for (p = strtok (line, delim); p; p = strtok (NULL, delim)) {
            if (idx == nth1) printf (fmt2, w1);   /* check and insert w1 */
            if (idx == nth2) printf (fmt2, w2);   /* and w2 in nth pos   */
            printf (!idx ? fmt1 : fmt2, p); idx++;        /* print token */
        }
        putchar ('\n');
    }

哪个会产生相同的输出,但如果行中存在nth1个或更少的标记(单词),则省略替换,例如

$ ./bin/replacenthword <dat/replcmt.txt
...
That's all folks

查看所有答案,如果您有任何问题,请告诉我。