代码在Visual C ++中无法按预期工作(来自bjarne stroustrup编程和原则书籍2n版本的示例)
Code doesn't work as intended in visual c++ (examples from bjarne stroustrup programming and principles book 2n version)
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
,然后尝试将其转换为int
,short
,double
,unsigned 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++的旧版本。
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 模板元编程:如何将参数包组合成新的参数包
- Qt Q串行端口未编程设备未关闭
- 模板元编程 - 尝试实现维度分析
- 我是编程新手
- C++编程从外部文本文件定义数组大小
- С++ wxWidgets:代码架构,设计原则和模式
- 了解算法的性能差异(如果以不同的编程语言实现)
- 使用 Gtkmm 以编程方式选择 Gtk::TextView 中的文本
- 如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
- 使用命名空间正确编程
- C++编程:运算符重载中的引用如何工作?
- Arduino 模块化编程与全局和设置
- C++ 运算符修改/元编程策略,用于不那么冗长的语法
- 在没有管理员权限的情况下,在 c++ 中以编程方式将程序添加到启动
- 代码在Visual C ++中无法按预期工作(来自bjarne stroustrup编程和原则书籍2n版本的示例)
- 使用"cin"进行演练 #7 获得不同的结果 编程:使用C++的原则和实践 (Stroustrup) 第 4 章
- 编程:cout问题的原则和实践
- 从输入中获取一个数字和一个单位作为双精度和字符串——编程:使用c++的原则和实践