输出错了

时间:2012-10-30 11:36:43

标签: c++ cin

我现在正在教自己C / C ++,我参加了练习(从我正在阅读的书中)来编写一个可以产生这样输出的程序:

Enter your first name: Flip
Enter your last name: Fleming
Here’s the information in a single string: Fleming, Flip

使用结构。但我的输出结果如下:

Enter your first name: Flip
Enter your last name: Fleming
Here’s the information in a single string: , 

这是代码。它相当简短,所以不难读懂:)

#include <iostream>
#include <cstring>

using namespace std;

struct Person {
    char* firstName;
    char* lastName;
};

char* getName(void);

int main() {
    Person* ps = new Person;
    cout << "Enter your first name: ";
    char* name;
    name = getName();
    ps->firstName = name;
    cout << "Enter your last name: ";
    char* lastname;
    lastname = getName();
    ps->lastName = lastname;
    cout << "Here's the information in a single string: "
            << ps->lastName << ", " << ps->firstName;
    delete ps;
    delete name;
    delete lastname;

    return 0;
}

char* getName() {
    char temp[100];
    cin >> temp;
    cin.getline(temp, 100);
    char* pn = new char[strlen(temp) + 1];
    strcpy(pn, temp);

    return pn;
}

4 个答案:

答案 0 :(得分:5)

首先,没有C / C ++ 这样的东西。你混合它们,这是错误的。由于您使用的是C ++标题/ new / using,我假设您需要C ++,因此以下是修复代码的方法:

  • 将所有char*char[]替换为std::string
  • 摆脱动态分配

因此,一些变化将是:

struct Person {
    std::string firstName;
    std::string lastName;
};

Person ps;

答案 1 :(得分:3)

您正在使用:

cin >> temp;
cin.getline(temp, 100);

您可能会在一行末尾用空字符串覆盖已有的内容。

只使用其中一个。

如果您坚持使用cin >>,可以考虑设置width()以防止缓冲区溢出。

答案 2 :(得分:2)

不不不,而且太复杂了。使用真正的C ++习语。该计划可以像这样简单:

#include <string>
#include <iostream>

int main()
{
    std::string firstName, lastName;

    if (!(std::cout << "Your first name: "  &&
          std::getline(std::cin, firstName) &&
          std::cout << "Your last name: "   &&
          std::getline(std::cin, lastName)     ))
    {
        std::cerr << "Error: unexpected end of input!\n";
        return 0;
    }

    std::cout << "You are " << firstName << " " << lastName << ".\n";
}

作为主题的变体,您可以将每个getline置于循环中,直到用户输入非空行:

std::cout >> "Your first name: ";
for ( ; ; )
{
    if (!(std::getline(std::cin, firstName))
    {
        std::cerr << "Error: unexpected end of input.\n"; 
        return 0;
    }
    if (!firstName.empty())
    {
        break;
    }
    std::cout << "Sorry, please repeat - your first name: ";
}

答案 3 :(得分:2)

首先,当前问题是您从std::cin阅读了两次:首先使用operator>>,然后使用getline。选择其中一个。

但是让我们稍微简化你的代码。有太多的错误来源。指针很棘手,因为它们可能指向错误的东西,或者您可能忘记删除对象或删除它们两次。作为字符串的C风格的char数组很糟糕,因为它们不是字符串,并且它们的行为不像字符串。

所以让我们使用标准库的字符串类:

#include <iostream>
#include <string>

struct Person {
    std::string firstName;
    std::string lastName;
};

std::string getName(void);

int main() {
    Person ps;
    cout << "Enter your first name: ";
    std::string name = getName();
    ps.firstName = name;
    cout << "Enter your last name: ";
    std::string lastname = getName();
    ps.lastName = lastname;
    cout << "Here's the information in a single string: "
            << ps.lastName << ", " << ps.firstName;
}

std::string getName() {
    std::string temp;
    std::getline(cin, temp);
    return temp;
}

这是一个相当简单,几乎是机械的替代,基本上只是将char*替换为std::string,并删除不再需要的位。

当然,正如评论中指出的那样,我省略了所有形式的错误检查,真正的程序应该这样做。