簡體   English   中英

為什么以及何時必須在C ++中使用之前初始化字符串?

[英]Why and when do we have to initialize a string before using in C++?

我正在閱讀一些C ++教程,發現有時會初始化字符串(“ initialized”可能不是正確的術語),有時卻沒有。

為什么以及何時?

我正在閱讀的代碼是:

char name[50];
char lastname[50];
char fullname[100];
...
cin.getline ( name, 50 );
...
cin.getline ( lastname, 50 );
fullname[0] = '\0';            // strcat searches for '\0' to cat after
strcat ( fullname, name );     // Copy name into full name
strcat ( fullname, " " );      // We want to separate the names by a space
strcat ( fullname, lastname ); // Copy lastname onto the end of fullname

請有人解釋。

在C ++中,有字符數組,如char name[50] ,還有字符串類,如std::string

字符數組根據它們在C中的相同規則進行初始化-也就是說,如果它們是堆棧變量,則不進行初始化;如果是靜態/全局變量,則在加載時將其初始化為零-但是有例外基於系統細節,因此最好是假設它們從未初始化。

字符串類(如std :: string)在對象的構造函數階段被初始化-因此它們總是被初始化。

在您的特定代碼中,您正在使用固定長度的字符數組。 它們通常以null終止,但可能並不總是-特別是cin.getline ( name, 50 ); 將讀取完整的50個字符,並且如果輸入的字符數少於或等於49個,則該數據將以null終止,但是由於沒有空間可容納50個以上的字符,因此如果輸入的字符數為50個或更多,則不會以null終止-這會對您的strcat產生影響,因為strcat假定數據以null結尾-您必須使用strncat來確保代碼安全。

與其他任何數據類型一樣。 默認情況下,局部變量包含垃圾值。 因此,如果要讀取其值,則可以對其進行初始化。 但是,如果您知道將要寫入變量,則可以跳過初始化部分。

例如:

char a[20]; //local variable

包含垃圾,因此您需要在讀取之前向其中寫入一些有意義的數據。 但是,如果您只寫它,則可以跳過初始化。

您所擁有的在堆棧上有一個分配。 編譯器不保證分配的內存為空,因此您可以在其上放置垃圾,這就是為什么您需要填充0來清除垃圾的原因。

你可以做到

memset(pointer, '0', size);

char a[50]

memset(a, NULL, sizeof(char)*50);

當取決於您的操作時,如果您想在其中寫入一些數據並進行讀取,則\\ 0可能會節省您的時間,因為這是截止日期;如果您想讀取所有數據,則將50字節char a [50]設置為char忽略\\ 0,因此您需要清除數據。 解決方法是清除^^內部的數據。

first_namelast_name不會立即初始化,因為接下來的兩行會在after和full_name到0終止符后立即對其進行初始化,因此它將表示一個空字符串,可以將其與std :: strcat連接。

char first_name[50];
char last_name[50];

// There is no need to initialize first_name and last_name,
// they will contain garbage as with any uninitialized values but they get
// overwritten here when reading from stdin anyways.
cin.getline ( first_name, 50 );
cin.getline ( last_name, 50 );

char full_name[100];
// Again full_name contains garbage, so it gets a 0 terminator here in order
// to have it represent an empty string.
full_name[0] = '\0';

// full_name had to be an empty string in order to concatenate
// onto it using strcat
strcat ( full_name, first_name );
strcat ( full_name, " " );
strcat ( full_name, last_name );

話雖這么說,這些都是C樣式的字符串,您很可能更喜歡只使用std::string

cin.getline不使用或檢查您傳入的緩沖區的原始值,因此對於該功能,無需初始化緩沖區。

相比之下, strcat檢查現有緩沖區的內容,以確定應在指定的字符串字符上附加的位置。 因此,使用strcat ,不僅必須隨意初始化緩沖區,而且還必須初始化一些零字節來標記邏輯字符串末尾位置。


正如其他人所說,顯示的代碼非常不安全。 這是不安全的,因為(我在撰寫本文時尚未對此進行評論)維護程序員可能沒有意識到full_name具有確切的緩沖區大小來容納最大長度的名字,空格和最大大小的姓氏。 至少應該在評論中對此進行了解釋。

但是比注釋更好,應該使用更安全的長度檢查功能。

並且除了學習之外,更好的方法是使用諸如std::string類的字符串類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM