[英]Printing strange result
为什么对c2.view()的调用会同时打印出ID和客户ID的名称?
我凝视了一段时间,找不到原因。 我或者错过了一些非常明显的东西,或者我不了解cstrings是如何工作的:)
客户.h
#ifndef CUSTOMER_H
#define CUSTOMER_H
class Customer
{
private:
char accountID[6];
char name[30];
public:
Customer();
Customer(char[], char[]);
void view();
Customer operator=(const Customer&);
};
#endif
客户.cpp
#include <string>
#include <iostream>
#include "Customer.h"
using namespace std;
Customer::Customer()
{
strcpy(accountID, "");
strcpy(name, "");
}
Customer::Customer(char acc[], char n[])
{
strcpy(accountID, acc);
strcpy(name, n);
}
void Customer::view()
{
cout << "Customer name: " << name << endl;
cout << "Customer ID: " << accountID <<endl;
}
Customer Customer::operator=(const Customer& right)
{
strcpy(accountID, right.accountID);
strcpy(name, right.name);
return* this;
}
驱动程序
#include <iostream>
#include "Customer.h"
using namespace std;
int main()
{
char id[] = "123456";
char n[] = "Bob";
Customer c1;
Customer c2(id, n);
c1.view();
c2.view();
system("pause");
return 0;
}
输出:
Customer name:
Customer ID:
Customer name: Bob
Customer ID: 123456Bob
Press any key to continue . . .
您正在传递包含七个字符的字符串:
char id[] = "123456"; // one more character for null termination '\0'
但是您的数组的大小为6。因此,当您打印accountId
,您将超出'6'
字符并打印出其旁边的所有内容,在这种情况下,该内容恰好是name
的内容。
使用std::strings
代替字符数组std::strings
很多麻烦。
使用C ++ std::string
。 您正在书写超出accountID
成员的范围的信息。 此char id[] = "123456";
有七个要素。
在这种情况下发生的情况是,终止的空字符首先以name[0]
结尾,然后被strcpy (name, n)
覆盖strcpy (name, n)
并且您得到一个连续的序列123456Bob\\0
因为accoutID的长度为6,并且当您在n中使用strcpy时,您覆盖了accountID的终止符,该终止符溢出为name [0]
strcpy
复制直到到达空终止符; \\0
因为您还没有定义,并且正在运行调试,所以名称恰好占用了ID旁边的内存,并且还被复制到ID的缓冲区中。
如果要构建发行版,则很可能只是在那儿胡扯。 无论哪种方式,如果您使用C字符串,则在所有字符串的末尾都需要空终止符。
strcpy
的实现类似于:
while (*ptr2 != '\0')
{
// copy string2 into string1's buffer until we reach it's null termintor
*ptr1 = *ptr2
ptr1++;
ptr2++;
}
*(ptr1 + 1) = '\0' // append null terminator
如您所见,它依赖于null终止符,如果不存在,则将导致缓冲区溢出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.