-1

我有函数,可以保存参数中的值。而且我必须实现两种方式,接受输入 - 作为 achar*然后通过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 的值...所以 Name:John, Surname: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,它只是不接受 name 和 surname 参数。所有值都保存到char **数组中。

您能否建议我,如何处理这种情况,以便能够正确接受两种输入?

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

4

3 回答 3

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,则不会在 destination 末尾隐式附加空字符(因此,在这种情况下,destination 可能不是以空结尾的 C 字符串)。

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

于 2013-04-13T04:55:43.913 回答
2

问题不在于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: %.*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()不会终止缓冲区;在这个例子中不需要,因为打印是仔细完成的。)

于 2013-04-13T05:07:00.013 回答
0

因为我们不知道lID等人的数据类型。因此sizeof很难评论。除了为什么不使用stringSTL 的容器

于 2013-04-13T05:00:11.287 回答