【问题标题】:Strcpy implementation in CC中的Strcpy实现
【发布时间】:2013-01-06 18:00:06
【问题描述】:

所以,我在 C 中看到了这个 strcpy 实现:

void strcpy1(char dest[], const char source[])
{
    int i = 0;
    while (1)
    {
        dest[i] = source[i];

        if (dest[i] == '\0')
        {
            break;
        }

        i++;
    } 
}

对我来说,它甚至将\0 从源复制到目标。

我也看过这个版本:

// Move the assignment into the test
void strcpy2(char dest[], const char source[]) 
{
    int i = 0;
    while ((dest[i] = source[i]) != '\0')
    {
        i++;
    } 
}

这对我来说,在尝试将 \0source 分配到 dest 时会中断。

正确的选择是什么,是否复制\0

【问题讨论】:

  • 复制空终止符是正确的。两个版本都这样做。
  • while\0 上中断时,复制已经由dest[i] = source[i] 完成。
  • @simonc - 您的评论将是正确答案
  • '\0' 表示字符串的结尾,它应该在那里,否则你将不知道你的字符串在哪里结束。

标签: c strcpy


【解决方案1】:

代码应如下所示:

char * strcpy(char *strDest, const char *strSrc)
{
    assert(strDest!=NULL && strSrc!=NULL);
    char *temp = strDest;
    while(*strDest++ = *strSrc++); // or while((*strDest++=*strSrc++) != '\0');
    return temp;
}

你可以NOT删除第二行char *temp = strDest;,直接返回strDest。这将导致返回的内容出错。例如,它不会返回正确的值(应该是 22)会检查返回的char * 的长度。

char src_str[] = "C programming language";
char dst_str[100];
printf("dst_str: %d\n", strlen(strcpy(dst_str, src_str)));

【讨论】:

  • 有没有比上述更好的方法?
  • 请注意:在您的示例中,您存储 dest 字符串的开头以避免在复制完成后返回其结尾,这是正确的,但是他的函数(返回类型为 @987654327 @and) 按值传递参数,因此(本地)指针算术不会影响外部指针,所以temp(即起始地址)不是强制性的,不是吗?
【解决方案2】:

都复制了终止符,因此都是正确的。

请注意,strcpy2() 首先进行分配(复制),然后进行比较。所以它会在意识到它之前复制终结器并停止。

另外,请注意名称以str 开头的函数是保留的,因此它们实际上都不是有效的“用户级”代码。

【讨论】:

  • 那么 (dest[i] = source[i]) 的最后一个赋值返回'\0'?我认为如果分配正确,分配总是返回“1”或 true。
  • @Assignments 评估为分配的值。我完全不确定“正确分配”是什么意思。 “错误分配”的例子是什么?我认为 C 中不存在这个概念。
  • 根据 C 2011 7.31.12 和 .13,仅保留以“str”小写字母开头的名称。
  • 如果strcpy函数中dest的大小未知怎么办?如何进行安全复制?
【解决方案3】:

你错了。两者都复制\0(NUL 终止符)字符。您必须始终复制 NUL 终止符,否则您的字符串将被破坏:您永远不知道它何时/何​​地结束。

【讨论】:

    【解决方案4】:

    都复制了终止符,因此都是正确的。

    strcpy2() 首先进行复制,然后进行比较。因此它将复制终止符并停止。

    名称以str开头的函数是保留的,所以请使用任何其他变量或命名类型

    【讨论】:

      【解决方案5】:

      strcpy1()strcpy2() 都这样做。两者都将 NUL 字符复制到目标数组的末尾。

      【讨论】:

        【解决方案6】:

        这里是完整的实现。您不必考虑第一个字符串末尾的 \0,它将按照逻辑从第二个字符串自动复制

        //str copy function self made
        char *strcpynew(char *d, char *s){
           char *saved = d;
           while ((*d++ = *s++) != '\0');
        
           return saved; //returning starting address of s1
        }
        
        //default function that is run by C everytime
        int main(){
        
            //FOR STRCPY 
            char s1[] = "rahul"; //initializing strings
            char s2[] = "arora"; //initializing strings
            strcpynew(s1, s2);
            printf("strcpy: %s\n", s1); //updated string after strcpy
        }
        

        【讨论】:

          【解决方案7】:

          你可以使用这段代码,越简单越好! 在 while() 中,我们逐个复制 char 并将指针移动到下一个。当最后一个字符 \0 将通过并复制,而接收 0 并停止。

              void StrCopy( char* _dst, const char* _src )
              {
                 while((*_dst++ = *_src++));
              }
          

          【讨论】:

          • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
          【解决方案8】:
          char * strcpy(char *strDest, const char *strSrc)
          {
              assert(strDest!=NULL && strSrc!=NULL);
              assert(strSrc + strlen(strSrc) < d || strSrc > strDest);  // see note
          
              char *temp = strDest;
              while(*strDest++ = *strSrc++);
                  return temp;
          }
          

          //如果不检查第4行,新字符串会覆盖旧字符串,包括空分隔符,导致复制无法停止。

          【讨论】:

            【解决方案9】:

            两者都复制 '\0'。如果你想完全模仿原始的strcpy,这就是你必须做的

            【讨论】:

              猜你喜欢
              • 2021-08-12
              • 2013-10-18
              • 2015-03-19
              • 2020-10-11
              • 1970-01-01
              • 2020-08-16
              • 2021-03-28
              • 2012-10-07
              • 1970-01-01
              相关资源
              最近更新 更多