我有函数,可以保存参数中的值。我必须实现两种方式,接受输入 - 作为char*
,然后通过strncpy
。
即: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等。 Neverthless它打印出值,保存为最后一个:
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
类似,它只是不带名字和姓氏参数。
所有值都保存到char **
数组。
你能否告诉我,如何处理这种情况,能够正确接受两种输入?
Ps:对于char*
输入整个程序工作正常,所以我不指望那里有任何错误..
Pps:请不要建议我使用字符串或我在这里不使用的任何其他结构 - 我对进口非常有限,因此我使用char *和其他东西......
答案 0 :(得分:3)
我认为你不应该在这里使用sizeof。 strncpy需要字符串的长度(要从目标字符串复制到源字符串的字符数)。
sizeof是指针的大小(例如sizrof(IID)=地址大小,我的系统是4)。
我认为你需要strlen()。此外,这需要在源指针上调用,而不是在目标指针上调用。
strncpy(lID, "987654/3210", strlen ("987654/3210"));
确保IID足够复制字符串,否则缓冲区溢出可能会有问题
阅读char * strncpy ( char * destination, const char * source, size_t num );和
从字符串中复制字符 将源的前num个字符复制到目标。如果在复制num个字符之前找到源C字符串的结尾(由空字符表示),则使用零填充目标,直到已经写入总数为num个字符。
感谢@JonathanLeffler :( strlen()意味着数据不会以空值终止。这很糟糕。至少复制strlen()+ 1个字节来获取空终结符)
注意:如果source长于num,则在目标的末尾不会隐式附加空字符(因此,在这种情况下,目标可能不是空终止的C字符串)。
答案 1 :(得分:2)
问题不在strncpy()
操作中。它是你未向我们展示的材料:
c.Add()
c.Resettle()
c.Print()
其中一个或多个有问题,但由于我们还没有看到它们,我们无法帮助您调试它们。
strncpy()
在对voodoogiant的answer的评论中讨论了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: %.*s\n", (int)sizeof(buffer), buffer);
strncpy(buffer, "123456/7890", strlen("123456/7890"));
printf("After: %.*s\n", (int)sizeof(buffer), buffer);
return(0);
}
输出:
Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
After: 123456/7890XXXXXXXXXXXXXXXXXXXXX
(是的,我很清楚memset()
没有空终止缓冲区;对于这个例子它不需要,因为打印是小心的。)
答案 2 :(得分:0)
因为我们不知道lID
等人的数据类型。因此sizeof
很难发表评论。此外,为什么不使用STL的string
容器