参数中char*和strncpy值之间的差异

Difference between char* and strncpy values in the argument

本文关键字:之间 strncpy char 参数      更新时间:2023-10-16

我有一个函数,它保存了参数中的值。我必须实现两种方式,接受输入-作为char*,然后通过strncpy

Ie: a . Add("123456/7890", "John", "Doe", "2000-01-01", "Main street", "Seattle");

它可以正常工作,直到我使用strncpy:

bool status;
char lID[12], lDate[12], lName[50], lSurname[50], lStreet[50], lCity[50];  
strncpy(lID, "123456/7890", sizeof ( lID));
strncpy(lName, "John", sizeof ( lName));
strncpy(lSurname, "Doe", sizeof ( lSurname));
strncpy(lDate, "2000-01-01", sizeof ( lDate));
strncpy(lStreet, "Main street", sizeof ( lStreet));
strncpy(lCity, "Seattle", sizeof ( lCity));
status = c . Add(lID, lName, lSurname, lDate, lStreet, lCity);
//is true 
strncpy(lID, "987654/3210", sizeof ( lID));
strncpy(lName, "Freddy", sizeof ( lName));
strncpy(lSurname, "Kruger", sizeof ( lSurname));
strncpy(lDate, "2001-02-03", sizeof ( lDate));
strncpy(lStreet, "Elm street", sizeof ( lStreet));
strncpy(lCity, "Sacramento", sizeof ( lCity));
// notice, that I don't even save it at this point
strncpy(lID, "123456/7890", sizeof ( lID));
strncpy(lDate, "2002-12-05", sizeof ( lDate));
strncpy(lStreet, "Sunset boulevard", sizeof ( lStreet));
strncpy(lCity, "Los Angeles", sizeof ( lCity));
status = c . Resettle(lID, lDate, lStreet, lCity);
status = c . Print(cout, "123456/7890");
//is true
在这一点上,我想打印出ID 123456/7890的值…姓名:John,姓氏:Doe等等。尽管如此,它还是打印出最后保存的值:
123456/7890 Freddy Kruger
2002-12-05 Sunset boulevard Los Angeles
2002-12-05 Sunset boulevard Los Angeles

我的Add声明为:

  bool Add(const char * id,
        const char * name,
        const char * surname,
        const char * date,
        const char * street,
        const char * city);

Resettle函数的声明类似于Add,它只是不接受name和姓氏参数。所有值保存到char **数组

你能告诉我,如何处理这种情况,能够正确地接受两种输入吗?

Ps:对于char*输入整个程序工作正常,所以我不希望有任何错误。Pps:请不要建议我使用字符串或任何其他我在这里不使用的结构-我对导入非常有限,因此我使用char*和其他东西…

我认为你不应该在这里使用sizeof。Strncpy需要字符串的长度(从目标字符串复制到源字符串的字符数)。

sizeof是指针的大小(例如sizeof (IID) =地址大小,在我的系统中是4)。

我认为你需要strlen()。此外,这需要在源指针上调用,而不是在目标指针上调用。

strncpy(lID, "987654/3210", strlen ("987654/3210"));

确保IID足够长以复制字符串,否则可能会出现缓冲区溢出问题

read char * strncpy (char * destination, const char * source, size_num);和

从字符串中复制字符将源的第一个num字符复制到目标。如果在复制num个字符之前找到源C字符串的末尾(用空字符表示),则目的地将用零填充,直到总共写入num个字符为止。

感谢@JonathanLeffler: ( strlen()意味着数据不会以null结尾。这是不好的。至少复制strlen() + 1字节以获得空终止符)

注意:如果source大于num,则不会在destination的末尾隐式添加空字符(因此,在这种情况下,destination可能不是以空结尾的C字符串)。

另请参阅:size_t strlen (const char * str);

问题不在strncpy()操作中。是在你们没有给我们看的材料里:

c.Add()
c.Resettle()
c.Print()

其中一个或多个有问题,但由于我们还不能看到它们,我们无法帮助您调试它们。


strncpy()的演示

在voodoogiant的回答的评论中有一个关于strncpy()行为的讨论。下面是一个示例:

strncpy(target, "string", strlen("string"));

不终止输出:

#include <string.h>
#include <stdio.h>
int main(void)
{
    char buffer[32];
    memset(buffer, 'X', sizeof(buffer));
    printf("Before: %.*sn", (int)sizeof(buffer), buffer);
    strncpy(buffer, "123456/7890", strlen("123456/7890"));
    printf("After:  %.*sn", (int)sizeof(buffer), buffer);
    return(0);
}
输出:

Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
After:  123456/7890XXXXXXXXXXXXXXXXXXXXX

(是的,我很清楚memset()不会null终止缓冲区;在本例中不需要这样做,因为打印是仔细完成的。)

由于我们不知道lID等人的数据类型,因此sizeof很难评论。此外,为什么不使用STL

中的string容器呢?