【问题标题】:Copying string using strncpy cause garbage value in output [duplicate]使用 strncpy 复制字符串会导致输出中出现垃圾值 [重复]
【发布时间】:2017-11-22 08:22:20
【问题描述】:

我有一个文件名“test.mf”作为字符指针。我想将此文件的扩展名更改为“test.pfb”。我正在为此编写一个简单的代码,但它会导致打印一些垃圾字符。在在线 C 编译器上运行相同的代码不会产生垃圾值,但使用 GCC 运行它会产生垃圾值。 如果我能以更好、更快的方式实现相同的目标(将 .mf 文件的文件扩展名更改为 .pfb),请提出建议。我是新手,所以请忽略愚蠢的错误。

代码

char *Get_PFB_font_file_name(char *TTF_Font_name) 
{
    size_t alen = strlen(TTF_Font_name);
    alen = alen+1; 
    char mystring[alen];
    const char* extension = ".pfb";
    char *PFB_File= malloc(alen+1);
    strncpy(mystring, TTF_Font_name, alen-4);
    strcat( mystring, extension );
    strncpy(PFB_File, mystring, alen);

    if(!PFB_File)
    {
        printf("error in get TTX conversion function");
        exit(1);
    } 
    return PFB_File;
}

int main ( void )
{
    char *MF_Font_file_name = "test.mf";
    char *PFB_Font_file_name;
    PFB_Font_file_name = Get_PFB_font_file_name(MF_Font_file_name);
    printf("PFB font file name is %s \n", PFB_Font_file_name); // garbage value here (test�.p)

    return 0;
}

【问题讨论】:

  • strncpy(mystring, TTF_Font_name, alen-4);: 那不是 nul-terminate 对吧?
  • @EdHeal 确保没有使用 C++ 编译器 :)
  • The strncpy function 在一种情况下可能不会终止字符串。这会发生在你身上。
  • 然后strcatWTF? 所以在你第一次打电话给strncpy 之后添加mystring[alen-4] = 0;strcat 之前(你会想要确保mystringstrncpy(PFB_File, mystring, alen); 之后再次nul-terminated
  • 你忘记了字符串的空终止

标签: c


【解决方案1】:

关于strncpy:

strncpy() 函数与 strcpy 类似,不同之处在于最多复制 n 个字节的 src。警告:如果 src 的前 n 个字节中没有空字节,则放在 dest 中的字符串不会以空结尾。

strncpy(mystring, TTF_Font_name, alen-4);
strcat( mystring, extension );

这具有未定义的行为,因为TTF_Font_namealen-4 长,因此上述警告/限制适用,并且strcat 无法正确计算mystring 的大小。

修复它的一种方法:只需在两行之间插入:

mystring[alen-4] = '\0';

【讨论】:

  • @AmmarUlHassan:抱歉编辑冲突。但是分号加了谢谢。
  • 我试过了,但垃圾值相同。我在同一个文件中有一个类似的函数,它几乎使用相同的变量名。会不会是它的原因?
  • 感谢它的工作。你认为这是做我想要实现的目标的正确方法吗?我可以改进吗?
  • 不要吝啬缓冲区大小。当然,是合理的,但我宁愿有一个 1000 字节太长的缓冲区,而不是一个 1 字节太短的缓冲区:)
  • 是的,我同意。如果我确定最大值为 30 个字符,那么 64 或 128 将是合理的。如果我想 100%(或尽可能接近安全),我会使用 PATH_MAX -- 与 gcc 一起提供高达 8192 字节 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 2011-02-24
  • 1970-01-01
  • 2016-03-03
  • 2020-04-20
相关资源
最近更新 更多