【问题标题】:Copying a string to an array implementation C将字符串复制到数组实现 C
【发布时间】:2015-10-25 12:28:54
【问题描述】:

我有一个问题,内容如下:

编写一个函数 int tokenCopy(char* dest, const char* src, int destSize) 将字符从给定的源字符串 src 复制到给定的目标缓冲区 dest,其大小为 destSize,直到:

出现源字符串的结尾,或者

目标缓冲区已满(允许需要的终止符),或

在输入字符串中找到一个空格字符

以先到者为准。如果由于找到空间而完成复制,则不复制该空间。目标字符串必须始终正确终止。如果源字符串的目标空间不足,则目标字符串必须是源字符串的正确终止的前导子字符串。

返回值是复制的字符数,不包括终止的空字节。

这是我目前的尝试:

   int tokenCopy(char* dest, const char* src, int destSize)
   {
        int the_slab = 0;
        for (; *src != ('\0' | ' '); the_slab++) 
        {   
            if ( *src == (32 | 0)) 
            {
                *dest = '\0';
                return the_slab;
            }
            *dest = *src;
            dest++;
            src++;  
         }
        *dest = '\0';
        return the_slab;      
       }

但是当测试失败时:

char buff[10];
int n = tokenCopy(buff, "This", 10);
printf("%d '%s'\n", n, buff);

因为它返回数字 7 而不是 4。 为什么它在处理前四个字母后没有终止?我不明白为什么 src 没有终止字节?

我做错了什么?我从概念上看不懂什么?

谢谢!

【问题讨论】:

  • 虽然,建议的副本看起来像一个副本,但那里的答案真的很混乱,并没有解决一个简单的问题。更糟糕的是,该示例将 "x" 等 c 字符串与 == 运算符进行了比较!
  • 谁在乎?问题出在基本的语言结构上,如果不是重复的话,会因为其他原因而关闭。有许多。许多人对复合条件句的基础知识有这样的误解。

标签: c


【解决方案1】:

*src != ('\0' | ' ') 并没有按照你的想法去做。

你需要一分为二:

*src != '\0' && *src!= ' '

同理:

  if ( *src == (32 | 0)) 

应该是:

 if ( *src == ' ' || *src )

使用字符表示 ' ' 总是比假设/依赖 ASCII 值更好。

事实上,循环内的整个条件都是冗余的:

   if ( *src == (32 | 0)) 
        {
            *dest = '\0';
            return the_slab;
        }

这就是您已经在 for 循环条件中测试的内容。

【讨论】:

  • 是的,基本上'\0' | ' '等价于' '(32 | 0)等价于32),因此空字符从未被测试。
【解决方案2】:

| 运算符对两个操作数执行按位“或”运算——这根本不是您想要的。

C bitwise OR operations

您的测试应使用逻辑 OR 运算符 ||:

if (*src == ' ' || *src == '\0')

【讨论】:

    【解决方案3】:

    这确实是一条注释,但 cmets 不允许正确的代码格式。我同意@JohnPirie 和@BlueMoon 的回答。

    这是一个使用数组索引比使用指针更简洁的示例,如下面的代码所示:

    int tokenCopy(char* dest, const char* src, int destSize)
    {
        int i;
        if (dest == NULL || source == NULL || destSize < 1) {
            // invalid input!
            return -1;
        }
        for (i = 0; i < (destSize-1) && src[i] != '\0' && src[i] != ' '; i++) {   
            dest[i] = src[i];
        }
        dest[i] = '\0';
        return i;
    }
    

    【讨论】:

      【解决方案4】:

      运算符| 是位(或)运算符。 ( *src == (32 | 0))if ( *src == 32 ) 相同的指令。因为32|0==32; 还记得逻辑表吗?:

      0 | 0 = 0
      0 | 1 = 1
      1 | 0 = 1
      1 | 1=  1
      

      bitwize 运算符将 source 的每一位与 dest 的每一位进行比较,由于 0 已关闭所有位,因此 32 中的每一位都保持不变

      您必须这样做才能使其正常工作:

      if ( (*src == 32) || (*src== 0)) { ...
      

      【讨论】:

        猜你喜欢
        • 2015-03-23
        • 1970-01-01
        • 1970-01-01
        • 2016-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-04
        • 1970-01-01
        相关资源
        最近更新 更多