【问题标题】:Strange results with memcopymemcpy 的奇怪结果
【发布时间】:2013-06-21 00:59:42
【问题描述】:

我正在将这样格式的字符串从一个程序发送到另一个程序:number lastname firstname middlei ID GPA

接收程序看到正确的字符串,并将该字符串存储到缓冲区中。字符串被标记化,并且数字在 switch 语句中使用。对应case的代码如下所示。

tok = strtok( arg, " " );
printf( "the first token is %s\n", tok );
memcpy( ptr->student.lname, tok, 10 );
tok = strtok( NULL, " " );
memcpy( ptr->student.fname, tok, 10 );
tok = strtok( NULL, " " );
ptr->student.initial = *tok;
tok = strtok( NULL, " " );
sscanf( tok, "%lu", &ptr->student.SID );
tok = strtok( NULL, " " );
sscanf( tok, "%f", &ptr->student.GPA );
// few more pointer and location initializations...
printf( "lu %s %s %c %f\n", ptr->student.SID, ptr->student.lname,
    ptr->student.fname, ptr->student.initial, ptr->student.GPA );

输入字符串为:5 lastnamereallylong,firstnamereallylong,X,1234,4.0

第一个程序缩短为:5 lastnamere firstnamer X 1234 4.0

第二个程序的输出如下:

the first tok is lastnamere
1234 lastnamereXfirstnamer firstnamer X 4.000000

有人可以帮我弄清楚这里发生了什么吗?我可以理解没有正确使用memcopy,但我认为这不会改变原始信息的顺序。

【问题讨论】:

    标签: c token memcpy


    【解决方案1】:

    这里发生的是未定义的行为:您告诉memcpy 复制令牌的前十个字符,但是当令牌长度超过十个字符时,这意味着字符串不会空终止。将此类字符串传递给 printf("%s", ...) 是未定义的行为。

    要解决此问题,如果您想保留固定长度的字符串,您应该通过设置ptr->student.lname[9] = '\0' 强制终止,或者使用strdup 来允许可变长度的字符串。

    最后,有一个线程安全的替代方法可以使用 strtok - 您可以使用 strtok_r

    【讨论】:

    • 使用 strncpy() 代替 memcpy()
    • 谢谢你们。我将名称的数组加长了一个,以便添加终止字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 2016-11-28
    • 2012-12-16
    • 2012-12-06
    • 2016-08-24
    • 2018-01-24
    相关资源
    最近更新 更多