【问题标题】:C - sprintf printing variable name [closed]C - sprintf 打印变量名
【发布时间】:2016-06-03 09:32:10
【问题描述】:

出于某种原因,sprintf 打印出我想在其内容中附加一个字符串的 char 数组的名称,从而使结果变得无用。它看起来不错,应该可以工作,只是它没有。 这是我所拥有的:

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

#define STR "ST%d"
#define MAX_MSG 80 

 char name[MAX_MSG+1] ;


int main(int argc, char **argv) {
printf("Before: %s\n",name); //--debug
    sprintf(name,STR,1); //format by 1
    printf("After: %s\n",name);
}

然后这给了我:

Before: name
After: nameST1

据我所知,这应该给我

Before: 
After: ST1

请帮忙。

【问题讨论】:

标签: c string printf


【解决方案1】:

您的第一个 printf 调用 Undefined Behavior,因为您没有初始化缓冲区。

你可以这样做:

chat name[50] = {0};

或者使用memset重置整个数组:

memset (name, 0x00, sizeof(name));

关于第二个printf 我想你没有发布你的真实代码。所以发布它,因为发布的代码不能导致nameST1作为第二个printf

【讨论】:

  • 我仍然有同样的结果
  • @i_use_the_internet 那你没有发布你的真实代码。
  • 我正在编辑:发布真实代码。贴出来的不能打印nameST1
  • @i_use_the_internet 也许您正在运行的代码不是您发布的代码。这可以解释为什么您的更改不会改变程序的输出。也许你应该发一个Minimal, Complete, and Verifiable example
  • printf 需要一个以NUL 结尾的字符串。未初始化的局部变量包含垃圾数据,因此不能保证 NUL 终止(并且可能包含 printf b0rk on 的值)。假设您将调用另一个函数来查看每个字符的十进制值(并且您提供数组的长度),那么这将非常好并且不会调用未定义的行为。也许稍微澄清一下答案?
【解决方案2】:

char name[] 可以包含垃圾值。如图所示,使用 memset 或初始化。

char name[50];
memset(name, 0, sizeof(name));

或使用

char name[50] = {0};

【讨论】:

  • 不,它不会“完成工作”。它会在你第二次调用该函数时无法正常工作,并且还会使代码线程不安全。
  • @Jite 如果数组是全局的,它已经归零了,因为 bss。所以我要说的是,将其声明为静态对数组值没有影响。
  • @LPs 如果它是全局或本地静态的,就像你说的那样没有区别。但是,您特别写了“本地静态未分配 bss”,这是错误的 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多