代码在Visual C ++中无法按预期工作(来自bjarne stroustrup编程和原则书籍2n版本的示例)

Code doesn't work as intended in visual c++ (examples from bjarne stroustrup programming and principles book 2n version)

本文关键字:原则 编程 stroustrup 2n 版本 bjarne 来自 Visual 工作 代码      更新时间:2023-10-16

Okey,因为我最近开始阅读有关C++并尝试使用C++第二版的编程原理和实践的书。

我是一个完全的新手,所以这可能是原因,但在这里。

好的,所以在书中,他们让你实现一个头 .h 文件而不是 (iostream) 等。所以它一开始就包含了所有这些,因为这本书不希望我们在学习开始时关注那些图书馆。 所以我实现了它并使用了它(不确定这是否与问题有关)。无论如何,在第77页,我被卡住了。

基本上,这是一个输入的错误值,它应该只显示 -1(或 0),因为 int 得到一个假值,等等 Carlos(字母,不是整数),所以 int 没有得到正确的值,所以应该工作的代码(并显示 0 或 -1,因为它是输入的错误值)是这样的根据书:

#include "std_lib_facilities.h"

using namespace std;
int main()
{
cout << "Please enter your first name and agen";
string first_name = "???"; // string variable // ("???” means “don’t know the name”)
int age = –1; // integer variable (–1 means “don’t know the age”)
cin >> first_name >> age; // read a string followed by an integer
cout << "Hello, " << first_name << " (age " << age << ")n";
}

这就是我写的:

#include "std_lib_facilities.h"

using namespace std;
int main()
{
cout << "Please enter your first name and age" << endl;
string First_Name = "???";
int Age = -1;
cin >> First_Name >> Age;
cout << "Hello, " << First_Name << "(age" << Age << ")" << endl;
keep_window_open();
return 0;
}

但是,对我来说,visual c ++ 的结果是当我例如编写 22 个 Carlos 时崩溃。 根据这本书,它应该输出你好,22岁(年龄-1)

但对我来说,当我输入卡洛斯这个词作为年龄的值后,它就会崩溃...... 当我运行和编译它时,我没有收到错误或任何东西,但是当我给出年龄的假值后它会崩溃。

我做错了什么? add:我知道我可以使用字符串来让它工作,但是我只是对为什么它不起作用感兴趣,因为我正在关注这本书,我希望遵循它而不会遇到这些问题,因为它打算工作。

这是我这样做时的 gif: http://imgur.com/a/ERjhz 解决方案:使用系统("暂停");而不是 keep_window_open(); 然而,在知道书中的代码并不总是有效的情况下阅读这本书仍然很烦人:(

嗯,这不是问题,但太快了,无法被我们的眼睛注意到。

我正在添加 keep_window_open() 的函数定义

inline void keep_window_open()
{
cin.clear();
cout << "Please enter a character to exitn";
char ch;
cin >> ch;
return;
}

如您所见,它只是从us获取字符输入 转发您将了解输入流及其缓冲区 因此,当您输入一个字符代替整数时,流(背景)中会标记错误,并且仅使用输入的字符之一(在您的情况下,"C"用于标记)。

我使用输入作为卡洛斯 22

所以现在输入流仍然有字符"a"、"r"、"l"、"o"、"s",22 所以现在">a">被用作keep_window_open函数的输入 程序无需等待您的输入即可结束 所以没有错误或崩溃,但由于字符已经在那里输入keep_window_open功能,所以它真的很快

问题出在keep_window_open中。这是一个棘手的功能,很难做到绝对正确。您可以将其替换为以下代码,该代码回避了该问题,但仅适用于Windows:

inline void keep_window_open()
{
system("pause");
}

或者使用这个稍微复杂的代码,试图考虑更多情况:

inline void keep_window_open()
{
cout << "Please enter a character to exitn";
if (!cin)
{
cin.clear();
cin.ignore(120, 'n');
}
char ch;
cin >> skipws >> ch;
}

(这假定您输入的行不超过 120 个字符。如果希望 120 不受任意限制,请将 120 替换为numeric_limits<streamsize>::max()。在这种情况下,std_lib_facilities.h 中的其他函数确实使用 120。您有很多或可能不必将#include <limits>指令添加到您的程序中)。

我已经在几种情况下进行了测试,它似乎适用于程序的正确和不正确输入,但使用它的风险自负。如果您的程序需要更复杂的输入,它仍然可能会或可能不会正常工作。

一个好的规则是始终排除最终用户是白痴,因此您需要以可以处理各种输入而不会崩溃的方式编写程序。因此,始终将输入数字读取为std::string,然后尝试将其转换为intshortdoubleunsigned int或您正在使用的任何数据类型。

您的代码应如下所示:

#include <cstdlib>
#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>
int main(int argc, char **argv)
{
int age;
std::string first_name;
std::string input_age;
std::cout << "Please enter your first name and age: " << std::endl;
std::cin >> first_name >> input_age; // Read the age as 'std::string'
try
{
age = std::stoi(input_age); // Try to convert age from 'std::string' to 'int'
std::cout << "Hello, " << first_name << " (" << age << ")" << std::endl;
}
catch(std::invalid_argument& ex) // 'std::stoi()' will throw 'std::invalid_argument' if it's not able to convert 'std::string' to 'int'
{
std::cerr << "Unable to convert input value ('" << input_age << "') to 'int'" << std::endl;
std::cerr << "Debug info: " << ex.what() << std::endl;
}
catch(std::out_of_range& ex) // 'std::stoi()' will throw 'std::out_of_range' if 'std::string' is too small or too big to store in a 'int'
{
std::cerr << "The input value (" << input_age << ") is out of range, please input a value inside the range" << std::endl;
std::cerr << "Debug info: " << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}

所以这与代码无关,与输入有关。

例如,当我写 22 卡洛斯时。

问题是代码要求First_Name然后Age,而不是Age然后First_Name。所以当你把22分放在First_Name上时,.exe就糊涂了。

例如,假设我做了这个

int y = 0;
cout << "Give me INT: ";
cin >> y;
cout >> "You put: " >> y;

当我运行程序并将其用于输入时

Give me INT: ghaisewofasd
*crashed*

这是一个问题,因为用户在代码请求 int 时给出一个字符串。

所以对于你的情况,与其写 22 卡洛斯,不如写卡洛斯 22还要记住,这本书可能不是那么正确,因为它不应该打印出Hello,(22)。现在像这样的事情崩溃了,如果发生这种情况,也许它是C++的旧版本。