2

当我运行以下代码并在提示输入 Golf 结构时插入新行(按 Enter)时,对该函数的第二次调用不会请求输入并且就像我再次按 Enter 一样完成。

我已经阅读了: cin.get() , cin.clear() , cin.ignore(...) 但似乎没有任何帮助。

我很确定它与多个 .cpp 文件和标题无关,但我按原样放置代码。

我正在使用 Visual Studio C++ 2010 - Express。

在此先感谢您的帮助!

头文件:golf.h

#ifndef GOLF_H
#define GOLF_H

const int Len = 40;

struct golf{

    char fullname[Len];
    int handicap;

};

int setgolf(golf & g );
void showgolf(const golf & g );

#endif

高尔夫.cpp

#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>


using namespace std;

int setgolf(golf & g ){

    cout << "Enter a name for the golf structure:" << endl;
    if  (cin.get(g.fullname,Len)) {     
        cin.get(); // deals with the '\n' incase the user inputs a valid string
        return 1;
    }
    else{
        return 0;
    }

}
void showgolf(const golf & g ){

    cout << "this golf structure contains the following information:" << endl;
    cout << "name:      " << g.fullname << endl ;
    cout << "handicap:  " << g.handicap << endl ;

}

主要的 ()

#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>


using namespace std;

int main()
{

    golf myGolf;

    // check of int setgolf(golf & g );
    int answ = setgolf(myGolf); //try to input empty string
    showgolf(myGolf);
    cout << "the number returned :" << answ << endl ;

    answ = setgolf(myGolf); // normal string
    showgolf(myGolf);
    cout << "the number returned :" << answ << endl ;

    return 0;
}
4

2 回答 2

2

当您在第一个提示中按 enter 时,就会发生此问题。输入流被标记为 eof,一个错误条件标志(这就是它返回 0 的原因)。然后输入流停止工作。

看来您使用的是 ISO 1998 之前的一种C++,而我认为您不需要它。但是,如果您想坚持您的方法,请执行以下操作:在cin.getline()(无需返回任何内容)之后写入:cin.clear(); cin.sync();,如下所示:

void setGolf(Golf &g)
{
    cout << "Enter a name for the golf structure:" << endl;
    getline( cin, g.fullname ) );

    cin.clear();
    cin.sync();
}

现在,关于使您的代码现代化。首先,您可以使用标准库的 class string,它能够存储字符串文字,甚至可以在需要时增长,而无需给出字符的最大值。这有点令人困惑,因为您包含了 header string,它将包含该类,但您没有使用它。使用string还具有其他优点,例如自动更正Golf结构中可能发生的潜在缓冲区溢出。因此,我会将您的结构更改为:

struct Golf{
    string fullname;
    int handicap;
};

现在您可以使用getline(), in utility,它读取整行并将其存储在 中string,为您完成所有的魔法。因此,您可以将golf.cpp文件更改为:

#include <utility>

//...

void setGolf(Golf &g)
{
    cout << "Enter a name for the golf structure:" << endl;
    getline( cin, g.fullname ) );   
}

您现在还可以将返回类型更改为void. 使用时不可能遇到任何类型的错误getline()。无论如何,请考虑到您可以返回bool(boolean type),它是一种内置类型,带有文字truefalse.

我敢肯定,您main()现在可以将您的样式更改为更简单的样式:

int main()
{

    Golf myGolf;

    setGolf(myGolf);
    showGolf(myGolf);

    setGolf(myGolf);
    showGolf(myGolf);

    return 0;
}

最后,您可以考虑将您的信息封装在一个类中,而不是一个结构中,但这是一个完全不同的问题。

希望这可以帮助。

于 2013-02-18T19:49:54.353 回答
0

您也可以离开char[]而不是用字符串替换它(我还在学习,所以如果我错了,请纠正我)。我认为当 std::cin.get(char *,Size)无法加载字符时,它会在 0 上打开 2 位,失败和错误,这是我的解决方案:

std::cin.get(g.fullname, Len);
if(!std::cin)
{
  std::cin.clear();
  std::cin.get();
  std::cout << "You inserted empty line." << std::endl;
  return 0;
}
于 2019-02-26T18:06:43.573 回答