2012-11-27 216 views
1

爲什麼調用c2.view()打印客戶ID的ID和名稱?打印奇怪的結果

我已經注視了這一段時間,並找不到原因。我要麼錯過了一些東西真的很明顯或者我不明白cstrings如何工作:)

Customer.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 

customer.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; 
} 

Driver.cpp

#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 . . . 
+1

使用'std :: string's。或者處理零終止的C字符串的痛苦。 – Mat

+0

這是一個班級作業。我別無選擇,只能使用cstring :) – Zzz

回答

4

你傳遞一個字符串七個大字:

char id[] = "123456"; // one more character for null termination '\0' 

但你的數組大小6.所以,當你打印accountId,你超越'6'字符,並打印出無論是在它旁邊,這在這種情況下恰好是name的內容。

通過使用std::strings而不是字符數組,可以省去很多麻煩。

+0

感謝您的幫助,我認爲我不需要考慮空終止符,並且c爲我做了! – Zzz

1

使用C++ std::string。你正在寫作超過accountID成員的範圍。這char id[] = "123456";有七個元素。

在這種情況下,什麼情況是,終止空字符首先在name[0]結束了,然後得到由strcpy (name, n)覆蓋,你會得到一個連續的序列123456Bob\0

1

因爲accoutID是delared長度爲6的,當你的strcpy在n中,您將覆蓋帳戶ID'終止符,即溢出到名稱[0]

1

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 

正如你所看到的,它依賴於空終止符,如果它不存在,你會得到一個緩衝區溢出。

+0

爲什麼它會走到string1的末尾(while while循環)?也許你正在考慮'strcat'? – user1520427

+0

@ user1520427哦,其實這只是愚蠢的。該算法用於附加而不是複製。我正在刪除它。 – evanmcdonnal