为什么strcpy(strerror(errno),“Hello”)没有复制“Hello”,但是{ptr = strerror(errno); strcpy(ptr,“Hello”);}呢?

时间:2013-05-14 15:11:09

标签: c pointers strcpy string.h strerror

请解释以下程序中发生了什么。

我检查了strerror(errno)在程序开头和结尾返回的地址,并确认每次都返回相同的地址。然后一旦确定,在第一种情况下,我继续分配相同的地址。地址为ptr,然后使用"Hello"将字符串strcpy()复制到其中。在案例II中,我尝试将"Hello"直接复制到strerror(errno)返回的地址我有奇怪的发现。如果您解释以下内容,我将不胜感激:

如果是第一种情况,我会将"Hello"复制到ptr,并且会在后续printf()ptr打印Hello时成功。但是,当我将strerror(errno)而不是ptr传递给printf(),它会打印旧的错误消息。ptr如何指向一条消息但strerror(errno)指向两个地址相同时的另一条消息?我确认两个地址都相同,我希望将"Hello"复制到ptr应该与将其复制到strerror(errno)的返回值相同。要加倍检查这个差异,然后我尝试将"Hello"直接复制到strerror(errno),但这次也不起作用,并打印出相同的旧错误字符串。但令人惊讶的是,此时我也验证了地址ptrstrerror(errno)一直都是一样的!它是如何可能的?如果它们是相同的,它们如何指向不同的字符串?一个到"Hello"和其他旧的自定义错误消息?

请解释背后的原因。

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main ()
{ char *ptr;
  FILE * fp;
  fp = fopen ("missingfile.txt","r");
  if (fp == NULL)
    printf ("%s\n",strerror(errno));
    printf("\n%p",strerror(errno));  //Initial address

    //Case1:
    ptr=strerror(errno);
    strcpy(ptr,"Hello");
    printf("\n%s",ptr);  //Prints Hello
    printf("\n%s",strerror(errno)); //Still prints old message


    //Case2:
    strcpy(strerror(errno),"Hello"); //Doesn't copy Hello there
    printf("\n%s",strerror(errno)); //Still prints old message


    printf("\n%p",strerror(errno)); //Address same as it was at start
    printf("\n%p",ptr);  //same address as above statement


  return 0;
}

输出

No such file or directory

00032508
Hello
No such file or directory
No such file or directory
00032508
00032508

2 个答案:

答案 0 :(得分:6)

//Case2:
strcpy(strerror(errno),"Hello"); //Doesn't copy Hello there
printf("\n%s",strerror(errno));

您对strerrorprintf的第二次电话会覆盖您复制的内容。

这是一种糟糕的形式,一直到处都是。

答案 1 :(得分:3)

来自the manual page

  

该字符串不得由应用程序修改,但可以通过后续调用 strerror()进行修改。

因此,虽然该函数没有返回const指针,但它应该进行修改,并且包括复制到它。

strerror实际上可能有一个static缓冲区,这就是你从它返回相同指针的原因。