2013-05-04 137 views
0

我想創建一個向量,它應該輸入strings (white space included),直到用戶輸入'!'創建一個字符串矢量:C++

下面是我的代碼:

#include <iostream> 
#include <vector> 
#include <string> 
#include <iterator> 

using namespace std; 


int main() 
{ 

    char buffer[100]; 
    string temp; 
    vector <string> vec; 


    while(1)//Shows Segmentation fault error while running, 
    //compiles succesfully 
    { 
    cout << "Enter String : "; 
    cin.get(buffer,100,'\n');//To ensure that whitespaces are also input 
    cout << "@@@@ " << buffer << endl ;//Shows correct input 

    cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
    //Clearing cin stream for any residual characters 
    temp.assign(buffer);//Assigning string the input "phrase" 
    cout << "###" << temp << endl;//Shows correct output 

    if (temp == "!") //if input is '!' character do not push on the vector a 
    //come out of the loop 
    break; 

    vec.push_back(temp);//push on the vector 
    temp.assign(NULL); //flush temp string 

    } 


    vector <string>::iterator p = vec.begin(); 
    //display thre vector 
    while(p != vec.end()) 
    { 
     cout << *p << endl; 
     p++; 
     } 

    return 0; 
    } 

它編譯成功,但在運行時拋出Segmentation fault錯誤。

無法弄清楚爲什麼?有人可以指出嗎?

此外,更智能的解決方案,讚賞一邊指出我的代碼有什麼問題。

感謝

+1

只需使用'std :: getline'來讀取帶有空格的字符串即可。您不需要施加不必要的最大長度,或擔心您的長度與您的緩衝區大小相匹配。 – chris 2013-05-04 18:40:03

回答

3

這將是原因:

temp.assign(NULL); 

std::string::assign()將嘗試讀取,直到空終止被發現,廢棄一個NULL指針是未定義的行爲:在這種情況下,分段錯誤。使用temp.clear()或者只是在每次迭代中創建一個新對象。

使用std::getline()讀取線,包括空格,並且避免了具有硬編碼的固定大小陣列(即buffer[100]):

std::string line; 
while (std::getline(std::cin, line) && line != "!") 
{ 
    vec.push_back(line); 
} 
1
while (getline(cin, temp) && temp != "!") 
{ 
    vec.push_back(temp); 
} 

那樣使用緩衝劑是更爲C事情比C做++。在C++中,通常有一種方法可以避免使用類進行顯式內存管理 - 這是一個很好的例子。儘管

+0

更像'while(getline(cin,temp)&& temp!=「!」){vec.push_back(temp);}'。 – chris 2013-05-04 18:42:31

+0

@chris感謝提示 – nullptr 2013-05-04 18:48:22

3

其他問題,在gdb(或可能的任何其他調試器)運行程序揭示了原因:

[email protected] ~$ g++ -o temp temp.cpp 
[email protected] ~$ gdb temp 
GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug 5 03:00:42 UTC 2012) 
Copyright 2004 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries ... done 

(gdb) run 
Starting program: /Users/tikal/temp 
Reading symbols for shared libraries ++............................. done 
Enter String : asd 
@@@@ asd 
###asd 

Program received signal EXC_BAD_ACCESS, Could not access memory. 
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000 
0x00007fff9081e6b0 in strlen() 
(gdb) backtrace 
#0 0x00007fff9081e6b0 in strlen() 
#1 0x00007fff9857ab95 in std::string::assign() 
#2 0x0000000100001642 in main() 
(gdb) 

從本質上講,temp.assign(NULL)是一個壞主意。您可以使用temp.clear(),或者不要打擾它(稍後您將重新分配它)。

+0

順便說一句,這裏有一個basic_string的參考資料:http://www.sgi.com/tech/stl/basic_string.html - 這裏的文檔暗示了這一點(「分配一個null-terminated *)的字符數組「),您必須傳入以空字符結尾的數組。 NULL不是這樣,所以我的猜測是屬於未定義的行爲。 – leander 2013-05-04 19:08:14