2011-09-30 96 views
0

此代碼應該詢問用戶名稱,然後在空間處將其拆分。爲什麼不是這個代碼工作? C++

應該把名字中的可變第一,並在德可變姓氏姓

#include <iostream> 

using namespace std; 

int main() 
{ 
char string[80]; 
char first[20]; 
char lastname[20]; 
bool f = true; 
int c = 0; 
cout << "Whats your Name? \n"; 
gets(string); 

for(int i =0; i < strlen(string); i++){ 
    if(string[i] == ' ') { 
     f = false; 
     c = 0; 
    } 

    if(f) { 
     first[c] = string[i]; 
    } else if(!f) { 
     lastname[c] = string[i]; 
    } 


    c++; 
} 

for(int i = 0; i < strlen(first); i++) { 
    cout << first[i] << "\n"; 
} 
for(int i = 0; i < strlen(lastname); i++) { 
    cout << lastname[i]<< "\n"; 
} 

return 0; 
} 
+1

發生什麼情況顯示任何異常? –

+1

如果你在C++中這樣做,不要使用'char *'來代替使用'std :: string',那麼你可以使用'find_first_of'來查找第一個空格。 – RedX

+7

定義**不工作**。 –

回答

5

除非您確實需要僅使用C函數編寫此代碼,否則使用C++字符串會更容易。

喜歡的東西(這是未經測試):

std::string input; 
std::string first; 
std::string lastname; 

// prompt the user 
std::cout << "What's your name? "; 
// get a line of input 
std::getline(std::cin, input); 

// find a space in the string 
size_t space = input.find_first_of(" "); 
// was the space found? 
if (space != std::string::npos) 
{ 
    // copy out the first and last names 
    first = input.substr(0, space); 
    lastname = input.substr(space + 1); 

    // output them to stdout 
    std::cout << first << std::endl << lastname << std::endl; 
} 

這意味着你不必擔心空的結束串或字符串的長度或類似的東西。正如flolo所說,你的代碼不會這樣做,因此肯定會遇到問題。 C字符串的內存佈局是末尾有一個空字節的字符數組,這就是strlen()知道字符串結尾的位置。而且,當有人輸入一個名字超過20個字符的時候,你的代碼將會有一段可怕的時間,這並不是特別不合理。

+0

謝謝,我知道他們是一個更好的方法來做到這一點.. – jhoevenaars

1

你不說你的程序是如何做的行爲是錯誤的。但我看到一個錯誤是由於C字符串是0終止的事實。您必須在「if ... == 」a first[c]=0;(將c重置爲0之前)以及循環之後加入lastname[c]=0

+0

來重寫類名...應該加上爲什麼這很重要:當0結束符丟失時,'strlen(first)'和'strlen(lastname)'將會失敗。 –

0

不是從別人提到的一些小問題:

if(f) { 
     first[c] = string[i]; 
    } else if(!f) { // <- this "if" statement looks like you did not understand "if .. else" 
     lastname[c] = string[i]; 
    } 

所以不如寫:

if(f) { 
     first[c] = string[i]; 
    } else { 
     lastname[c] = string[i]; 
    } 

而且部分

if(string[i] == ' ') { 
     f = false; 
     c = 0; 
} 

應該會更好

if(string[i] == ' ') { 
     f = false; 
     c = 0; 
     continue; 
} 

因爲否則您的lastname將始終包含領先空間。

1

談論困難的事情。它將使用 std::string更容易,但如果你堅持要用char[],不要使用gets (這是irremdially打破),但fgets,二是找到 字符串結束一勞永逸。因此,要麼(首選:

std::string line; 
std::getline(std::cin, line); 
if (! std::cin) 
    // Something when wrong... 
typedef std::string::const_iterator Iter; 
Iter begin = line.begin(); 
Iter end = line.end(); 

或:

char line[80]; 
if (fgets(line, stdin) == NULL) 
    // Something went wrong... 
typedef char const* Iter; 
Iter begin = line; 
Iter end = line + strlen(line); 
if (end != begin && *(end - 1) == '\n') 
    --end; 

然後找到第一個空間:

Iter pivot = std::find(begin, end, ' '); 

然後第一個和最後創建兩個字符串,可以:

std::string first(begin, pivot); 
std::string last(pivot == end ? end : pivot + 1); 

char first[80] = { '\0' }; // nul fill to ensure trailing '\0' 
std::copy(begin, pivot, first); 
char last[80] = { '\0' }; 
std::copy(pivot == end ? end : pivot + 1, end, last); 

然後輸出:

std::cout << first << std::endl; 
std::cout << last << std::endl; 

當然,如果你使用std::string,你甚至不需要創建 變量firstlast;你可以輸出一個臨時的:

std::cout << std::string(begin, pivot) << std::endl; 
std::cout << std::string(pivot == end ? end : pivot + 1, end) << std::endl;