每第 N 个单词插入字符串

Insert string every Nth word

在每第 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,现在我已经用它苦苦挣扎了几天,但我似乎真的不明白这里背后的逻辑。如何进行?

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

代码:

#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是必要的(我在评论中也有解释,我只是觉得Weather Vane的版本更简洁一点)。

这段代码产生的输出是:

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[] 的值。

希望对您有所帮助!

按字符逐个字符处理字符串并计算空格(只要您聚合空格等)并没有错,但是,还有另一种方法考虑一下这可能会提供更多的灵活性。您可以使用 strtok(在 string.h 中)来 标记化 您的输入字符串,而不是搜索空格。然后,只需计算 tokens(单词)并将添加的内容作为 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;
}

(注意: 您可以根据需要定制索引。例如,您可以在插入 nth[= 后增加索引 idx 51=] 个单词让它们按顺序插入,等等...)

例子Use/Output

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

由于您没有对要操作的字符串进行硬编码,因此您现在可以在发送的任何行中替换 nth1nth2 单词它,如果你愿意,可以放在整个文件中,例如

示例输入文件

$ 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

例子Use/Outputw/File

$ ./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

如果只想插入第nth个词如果后面有个词,那么你只需要改变顺序每个令牌的测试和打印。

    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

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