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

C++ 参数中char*和strncpy值之间的差异,c++,C++,我有一个函数,它保存了参数中的值。我必须实现两种方法,接受输入-作为char*然后通过strncpy 例如:a。添加(“123456/7890”、“约翰”、“能源部”、“2000-01-01”、“主街”、“西雅图”) 它工作正常,直到我使用strncpy: bool status; char lID[12], lDate[12], lName[50], lSurname[50], lStreet[50], lCity[50]; strncpy(lID, "123456/7890", siz

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

例如:
a。添加(“123456/7890”、“约翰”、“能源部”、“2000-01-01”、“主街”、“西雅图”)

它工作正常,直到我使用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的值。。。姓名:约翰,姓氏:多伊等。 但它会打印出保存为最后一个值的值:

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);
resetle
函数类似于
Add
,它只是不接受名称和姓氏参数。 所有值都保存到
char**
数组中

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

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

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

sizeof是指针的大小(例如sizrof(IID)=地址大小,从我的系统到它的4)

我想你需要斯特伦()。此外,这需要在源指针上调用,而不是在目标指针上调用

strncpy(lID, "987654/3210", strlen ("987654/3210"));
确保IID足够长,可以复制字符串,否则可能会出现缓冲区溢出问题

阅读,然后

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

感谢@JonathanLeffler:(strlen()表示数据不会以null结尾。这很糟糕。至少复制strlen()+1字节以获得null结尾)

注意:如果源长度大于num,则不会在目标的末尾隐式追加空字符(因此,在这种情况下,目标可能不是以空结尾的C字符串)


另外请阅读:

因为我们不知道
lID
等的数据类型,因此很难对
的大小进行评论。除了为什么不使用STL中的
字符串
容器

之外,问题不在
strncpy()
操作中。这是您未向我们展示的材料:

c.Add()
c.Resettle()
c.Print()
其中一个或多个存在问题,但由于我们还无法看到它们,因此无法帮助您调试它们


演示
strncpy()
在对的注释中讨论了
strncpy()
的行为。下面是一个演示:

strncpy(target, "string", strlen("string"));
不为null终止输出:

#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);
}

(是的,我很清楚
memset()
不会以null终止缓冲区;在本例中,它不需要以null终止缓冲区,因为打印过程非常小心。)

您没有显示变量的定义,例如
lID
,因此不可能说出哪里出了问题。如果它们是
char lID[XX]
,您需要担心一组问题(特别是,
strncpy()
不保证空终止),如果它们是
char*lID您还有一些其他问题需要担心。因为你在C++中工作,你不应该真的使用<代码> STRNCYPY()/<代码>或代码> > char < /代码> -你应该使用<代码> <代码>和<代码> STD::String 。当你学习一门语言时,你应该被教授该语言的最佳实践。嗯……我真的不知道……这些课程是用来练习算法的,所以我希望,他们希望我们在做作业时理解好指针……我没有更好的解释~~你的标题是
strcpy
,但是你的问题是
strncpy
。这不是我的想法……这是输入,我必须能够接受:-/the
strlen()
意味着数据不会以null结尾。那太糟糕了。至少复制
strlen()+1
字节以获得空终止符。@JonathanLeffler但根据strncpy()手册,它本身添加了空。。我在那里看到我贴的链接…是吗wrong@GrijeshChauhan:
strncpy()。当要求复制的长度不包含空值时(如使用
strlen()
的代码中),它不会添加空值。通过这些调用,您告诉它复制的非空字符数与字符串中的字符数一样多,这样它就不会在末尾复制空字符。@voodoogiant添加了链接和函数详细信息,如果不喜欢,您可以回滚到您的修订版。我已经更新了帖子…正如我在那里写的那样-我只限于包含,不能使用字符串。。。这是一个家庭作业,所以我必须按照说明去做……但别问我为什么这个例子也这么简单!
Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
After:  123456/7890XXXXXXXXXXXXXXXXXXXXX