char*函数在C中无法正确显示

mma*_*oka 2 c char

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

char *czas()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];
  time ( &rawtime );
  timeinfo = localtime ( &rawtime );
  strftime (buffer,80,"Now it's %I:%M%p.",timeinfo);
  return buffer;
}

int main()
{
printf("%s",czas());
system("PAUSE");
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么,但这个程序的结果只是"按任意键(...)".我也尝试将其打印为%c但它仍然无法正常工作.这个程序有什么问题?

And*_*ant 10

你正在返回一个指向局部变量('缓冲区')的指针,这是无效的,我很惊讶你没有收到关于它的警告.

当函数退出时,所有局部变量都不再存在(称为超出范围),并且它们的内存将用于其他目的.你正在返回一个指向这个记忆的指针,但不能保证现在会有什么.

在这种情况下,似乎在printf调用时,内存包含一个被视为空字符串的0.这实际上是非常幸运的,你很容易最终得到垃圾打印或程序崩溃.

要解决此问题,您可以将缓冲区传递给czas,或者让czas在堆上分配一个缓冲区,稍后您将释放该缓冲区.我会推荐前者,因为它与几乎所有库函数的工作方式一致.它还避免了调用者必须稍后释放指针的内存分配.

例如:

size_t czas(char* buffer, size_t buffer_size)
{
    time_t rawtime;
    struct tm * timeinfo;

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    return strftime (buffer, buffer_size,"Now it's %I:%M%p.",timeinfo);
}

int main()
{
    char buffer [80];
    if (czas(buffer, 80))
    {
      printf("%s\n",buffer);
    }
    else
    {
      printf("Call to czas failed");
    }
    system("PAUSE");
}
Run Code Online (Sandbox Code Playgroud)

更新:我没有注意到strftime采用了一个大小参数,我已经更新了代码以使用它并正确地从strftime传回结果.因此,这更加强大,您不会意外地溢出缓冲区.