C语言 反转字符串中的单词



我要反转字符串中的单词。我觉得我的方向是对的。但是我一直得到不稳定的输出,我忍不住想这和strncat()函数有关。你们有没有看到任何问题我决定处理它。我愿意听取其他方法的建议。

int main()
{
  int ch, ss=0, s=0;
  char x[3];
  char *word, string1[100], string2[100], temp[100];
  x[0]='y';
  while(x[0]=='y'||x[0]=='Y')
  {
    printf("Enter a String: ");
    fgets(string1, 100, stdin);
    if (string1[98] != 'n' && string1[99] == '') { while ( (ch = fgetc(stdin)) != EOF && ch != 'n'); }
    word = strtok(string1, " ");
    while(word != NULL)
    {
      s = strlen(word);
      ss=ss+s;
      strncpy(string2, word, s);
      strncat(string2, temp, ss);
      strncpy(temp, string2, ss);
      printf("string2: %sn",string2);
      printf("temp: %sn",temp);      
      word = strtok(NULL, " ");
    }
    printf("Run Again?(y/n):");
    fgets(x, 2, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != 'n');
  }
  return 0;
}

这是我的输出:

Enter a String: AAA BBB CCC DDD EEE
string2: AAA
temp: AAA
string2: BBBAAA
temp: BBBAAA
string2: CCCAAABBBAAA
temp: CCCAAABBB
string2: DDDAAABBBAAACCCAAABBB
temp: DDDAAABBBAAA
string2: EEE
AABBBAAACCCAAABBBDDDAAABBBAAA
temp: EEE
AABBBAAACCCA

您需要初始化"至少" strcat()参数的第一个字节,因为它期望它的参数以nul终止,所以

string2[0] = '';

会有帮助,但您第一次不需要strcat(),您可以使用strcpy()代替。

您在strncpy调用中没有复制足够的字符。

从手册页:

strncpy()函数与之相似,只是不超过n个字节的SRC被复制。因此,如果前n个字节中没有空字节src的字节数,结果不会以空结束。

由于您指定了字符串的确切长度,因此不会追加以NULL结尾的字节。

你需要给每一个加1:

  strncpy(string2, word, s+1);
  strncat(string2, temp, ss);   // strncat always NULL terminates
  strncpy(temp, string2, ss+1);
输出:

Enter a String: aaa bbb ccc ddd eee
string2: aaa
temp: aaa
string2: bbbaaa
temp: bbbaaa
string2: cccbbbaaa
temp: cccbbbaaa
string2: dddcccbbbaaa
temp: dddcccbbbaaa
string2: eee
dddcccbbbaaa
temp: eee
dddcccbbbaaa

最后一次迭代的分割行是因为fgets在缓冲区的末尾留下了换行符。您可以通过在strtok:

的分隔符列表中包含n来跳过它。
word = strtok(string1, " n");
...
word = strtok(NULL, " n");

很难判断你是否真的在尝试:

反转字符串

中的单词

反转字符串

如果你只是想反转整个字符串,那么把字符串分成标记就没有多大意义了,因为你所需要做的就是把原来的字符串倒序写出来。

从表面上看,简单地用开始指针'p'和结束指针'ep'沿着字符串向下走,并在找到space'ep'时反转两个指针之间的内容可能更容易。换句话说,将原字符串的新副本下移,并将'p'指向每个单词的开头,当'ep'指向该单词末尾(或字符串末尾)的空格时,只需将字符在位置反转即可。这将消除所有的复制和连接。

一种就地反转字符的方法是:

#include <stdio.h>
#include <string.h>
void strprev (char *begin, char *end);
int main (int argc, char **argv) {
    if (argc < 2) return 1;
    size_t len = strlen (argv[1]);
    char *p, *ep;
    char rev[len + 1]; /* a VLA is fine here   */
    strncpy (rev, argv[1], len + 1);     /* copy string to rev       */
    p = ep = rev;
    for (;;) {  /* for every char in rev */
        if (*ep && *ep != 'n') {        /* if not at end of rev, and */
            if (*ep == ' ' && ep > p) {  /* if ' ' and chars between  */
                strprev (p, ep - 1);     /* reverse between p and ep  */
                p = ep + 1;              /* advance p to next word    */
            }
        }
        else {  /* handle last word in rev */
            if (ep > p)
                strprev (p, ep - 1);
            break;
        }
        ep++;
    }
    printf ("n string  : %sn reverse : %snn", argv[1], rev);
    return 0;
}
/** strprev - reverse string given by begin and end pointers.
*  Takes valid string and swaps src & dest each iteration.
*  The original string is not preserved.
*  If str is not valid, no action taken.
*/
void strprev (char *begin, char *end)
{
    char tmp;
    if (!begin || !end) {
        printf ("%s() error: invalid begin or endn", __func__);
        return;
    }
    while (end > begin)
    {
        tmp = *end;
        *end-- = *begin;
        *begin++ = tmp;
    }
}

$ ./bin/strrevex_a "ABC DEF GHI JKL MNO"
 string  : ABC DEF GHI JKL MNO
 reverse : CBA FED IHG LKJ ONM

注意:如果你需要处理(跳过)单词之间的多个空格,那么在上面的代码中分配p = ep + 1;之前,它们需要被跳过。

如果你真的想要反转整个字符串,那就简单多了。让我知道哪一个是正确的目标,如果需要,我会进一步帮助你。

相关内容

  • 没有找到相关文章

最新更新