【问题标题】:What's wrong with printf in my strcat code?我的 strcat 代码中的 printf 有什么问题?
【发布时间】:2016-12-13 21:09:26
【问题描述】:

我已经制作了这个程序来模拟 strcat 功能,但是 printf 有一个我不明白的错误...

代码如下:

#include <stdio.h>

char *mystrcat(char *s1, char *s2);

int main(void)
{
    char *s1,*s2;
    s1="asdad";
    s2="asdad";
    s1=mystrcat(s1,s2);
    printf(s1);

    return 0;
}
char *mystrcat(char *s1,char *s2)
{
    int i,j;
    for(i=0;s1[i]<'\0';i++) ;
    for(j=0;s2[j]!='\0';j++) s1[i+j]=s2[j];
    s1[i+j]='\0';
    return s1;
}

【问题讨论】:

  • 2) s1 中没有空格来保存连接的字符串。
  • 作为附加说明,您可能不应该使用printf(s1),而应该使用puts(s1)printf("%s\n", s1)。特别是如果字符串不是编译时常量,如果它们碰巧包含格式说明符,那么将它们用作printf 的格式字符串是一个严重的问题。

标签: c printf strcat


【解决方案1】:

第一个问题是s1 没有足够的空间来追加s2。您需要s1 指向的缓冲区大小至少为strlen(s1) + strlen(s2) + 1+ 1 是NUL 终止符)。

第二个问题是字符串文字是只读的。您从"asdad" 分配s1,这会创建一个指向(可能)只读内存的指针。当然第一个问题意味着即使它是可写的,你也没有足够的空间来追加到末尾,但这是 C 语言中的常见缺陷之一,值得一提。

第三个问题(在another answer 中已经提到)是比较s1[i] &lt; '\0' 是错误的,您将无法正确找到s1 的长度,因为循环不会运行一次迭代。正确的条件与第二个循环 != '\0' 中的条件相同。 (从那时起,这掩盖了问题 1,您无意中从一开始就覆盖了 s1。)

【讨论】:

  • 小心“s1”的大小。由于s1char *,它的大小与它所指向的对象无关。
  • 非常感谢!您能否更具体地说明如何解决第二个问题?
  • @Metalingus 它可能会通过修复问题 1 来解决,例如,通过使 main 中的 s1 成为一个足够大的数组(而不是指针),或者通过动态分配 @987654338 @ 在知道所需的大小之后。
【解决方案2】:

至少,s1[i] &lt; '\0's1[i] &lt; 0 一样,总是假的。

【讨论】:

  • 一个char 可以是signed,这可以使s1[i] &lt; 0 为真,对吧?
  • FiddlingBits 提出了一个很好的观点:关系表达式不正确,但不是因为您指定的原因。例如,(int)(char)(-1) 在我的平台上导致 -1,而不是像 (int)(unsigned char)(-1) 那样的 255。同样,在前一种情况下,另一个平台可能会导致 255(或另一个值;并非每个实现都使用二进制补码),而 (int)(signed char)(-1) 会导致 -1。一些编译器甚至支持通过编译器标志使char 有符号或无符号。 char 的签名由 ISO C 标准由实现定义,因此 s1[i] &lt; 0 并不总是错误的。
猜你喜欢
  • 2011-07-28
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多