2011-09-30 199 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;