【问题标题】:passing pointer to strcat does not update the string将指针传递给 strcat 不会更新字符串
【发布时间】:2014-11-17 07:58:27
【问题描述】:

我正在按照 K&R 用 C 语言编写自己的 strcat 版本。这是我的代码:

#define MAXVALUE 1000

void concat(char *s, char *t)
{
    while (*s++)
        ;
    while (*s++ = *t++)
        ;
}

/* test */
int main()
{
    char s1[MAXVALUE];
    char s2[] = "Jim!";
    s1[0] = 'H', s1[1] = 'i', s1[2] = ' ';
    s1[3] = '\0';
    concat(s1, s2);
    printf("%s\n", s1);
    return 0;
}

这个想法是将s2 复制到s1 以获得“Hi Jim!”。我确保s1 足够大以包含两个字符串。但是,当我运行它时,它会输出“Hi”,所以基本上它不会更新字符串s1。我不知道为什么:s1 仍然指向s1[0] = 'H',并且在运行concat 之后,s1[3] 中的'\0' 应该已经被替换,s1 应该在@ 处以'\0' 终止987654334@.

附:请注意,在 K&R 中,我的 strcat 版本与标准库之一不匹配。特别是返回值是void。

【问题讨论】:

  • 您的第一个 while 超过了空终止符。改用while (*s) s++;,所以*s是循环后的空字符。
  • @Himanshu 不会迭代两次吗?一次在一段时间内,一次在括号内。我认为他写它的方式是正确的。首先它迭代直到 *s 结束然后将在*s*t 的末尾连接并递增到下一个元素。 @MOeehm 发表的评论是正确的。
  • @MOehm 是的,你是对的。在 while 之间插入 s-- 可以解决问题。感谢您的帮助,这是我犯的一个愚蠢的错误。

标签: c pointers while-loop strcat


【解决方案1】:

在您的代码中,问题是,在到达终止 NUL 之后,您正在推进指针 *s++,因此,它包含在目标字符串中,使得 printf() 被解释为结束细绳。根据字符串连接的设计规则,您需要删除[或替换,或覆盖]终止NUL并添加第二个字符串。

为避免终止 NUL 出现在输出字符串中,当指针到达 NUL 时不要增加指针,而是从该特定位置本身开始复制下一个字符串。

检查下面的代码。

#include <stdio.h>
#include <stdlib.h>

#define MAXVALUE 1000

void concat(char *s, char *t)
{
    while (*s)  s++;     //after NUL, do not increment, move on to copying
    while (*s++ = *t++)
        ;
}

/* test */
int main()
{
    char s1[MAXVALUE];
    char s2[] = "Jim!";
    s1[0] = 'H', s1[1] = 'i', s1[2] = ' ';
    s1[3] = '\0';
    concat(s1, s2);
    printf("%s\n", s1);
    return 0;
}

【讨论】:

    【解决方案2】:

    检查以下代码:

    void concat(char *s, char *t) 
    {
           while (*s != '\0')
              s++; 
               while (*s++ = *t++)
                          ;   
    }
    
    /* test */
    int main()
    {
       char s1[MAXVALUE];
       char s2[] = "Jim!";
       s1[0] = 'H', s1[1] = 'i', s1[2] = ' ';
       s1[3] = '\0';
       concat(s1, s2);
       printf("%s\n", s1);
       return 0;
    }
    

    【讨论】:

      【解决方案3】:

      感谢@MOehm,我通过简单地插入s-- 来修复代码,以补偿越过空终止符:

      void concat(char *s, char *t)
      {
          while (*s++)
              ;
          s--;
          while (*s++ = *t++)
              ;
      }
      

      【讨论】:

      • 为什么不简单地while (*s) s++;
      • 没有理由;只想对我的代码进行最小的更正。任何一个都可以。
      • 我问的原因是,我觉得走得太远,然后退后一步,不如一开始就省略这一步那么干净优雅……
      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2021-09-26
      • 2014-02-20
      相关资源
      最近更新 更多