C++偶数或奇数程序无法正常工作

C++ Even or Odd number program not working properly

本文关键字:常工作 工作 程序 C++      更新时间:2023-10-16

我是C++新手,我正在做在这里找到的练习:

http://www.learncpp.com/cpp-tutorial/32-arithmetic-operators/

我正在做测验 2,它告诉我共同创建一个从用户接收整数的程序,并且打印的整数为 true。所以我创建了以下代码:

#include "stdafx.h"
#include <iostream>
int getInteger()
{
    std::cout << "Insert an integer" << "n";
    int8_t x;
    std::cin >> x;
    return x;
}
bool isEven(int8_t x)
{
    bool b;
    b = false;
    std::cout << x % 2 << "n";
    if(x%2 == 0)
        {
            b = true;
        }
    return b;
}
void printResult(bool b)
{
    std::cout << std::boolalpha;
    std::cout << b << "n";
}
int main()
{
    int8_t x;
    x = getInteger();
    bool b;
    b = isEven(x);
    printResult(b);
    return 0;
}

所以,这就是问题所在。除非我错过了什么,否则这应该有效,对吧?确实如此,但仅适用于我从 0 到 10 输入的整数。出于某种原因,如果我输入 10 或 12,它会打印 false,但它在 2、4、6 和 8 上工作正常。为什么会这样?

你有以下代码:

int8_t x;
std::cin >> x;

int8_t只是平台char的别名,当它以char类型作为参数输入一个字符而不是整数时,std::istream。因此,解决方案是使用类型 int,您应该从一开始就使用它,因为在这种情况下根本没有理由使用int8_t

此函数返回的类型与它应该返回的类型不同:

int getInteger()
{
    std::cout << "Insert an integer" << "n";
    int8_t x;
    std::cin >> x;
    return x;
}

int应该工作正常而不是int8_t,并在此处查看为什么文档

正如

你所看到的getInteger()接受字符文本翻译的输入,而不是数字,因为int8_t实际上扩展到char

要解决此问题,请在第 1 位取一个整数并转换为 int8_t 类型:

int getInteger()
{
    std::cout << "Insert an integer" << "n";
    int x; // <<<<
    std::cin >> x;
    return x;
}

x = (int8_t)getInteger();

Alex on learncpp.com 指定最好使用固定宽度整数的原因是,当程序在不同的编译器上编译时,程序的结果不会改变。对于像charint这样的非固定宽度的整型,情况并非如此,因为类型的大小在编译器之间会有所不同。正如@Slava所指出的,int8_tchar的固定宽度积分类型,因此两者都与仅在内存中存储单个字符的变量一起使用。

每当程序可能在不同的编译器或机器中使用时,请使用固定宽度的整数,并且结果与编译器和平台无关非常重要。由于程序要求用户输入任何整数,因此要使用固定宽度的整数,最好使用 int32_tint8_t和"char"适合获取数字(即0-9)。 int16_t适用于介于 -2^16/2(等于 -2^15)和 2^15-1(即介于 -32 768 和 32 767 之间)之间的整数。'int32_t' 适用于 -2^31 和 2^31-1 之间的整数(即介于 -2 147 483 648 和 2 147 483 647 之间)。

正如 Alex 稍后在 5.10 — std::cin、提取和处理无效文本输入中所解释的那样,处理所有可能的无效用户输入非常重要。

以下是一些更新的代码,可以工作,处理无效的用户输入,并循环询问用户是否要检查另一个数字是偶数还是奇数,等等:

// StackOverflow C++ Even or Odd number program.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream> // for cin and cout
//include <cmath>	// pow is no longer used and is commented out below.
#include <cstdint> // std::int32_t
// I changed the variable output for the function to int32_t, since that is the type being returned.
std::int32_t getInteger()
{
	/* If you don't understand some parts, like do-while loops and
	handling invalid user input, come back to it after learning it,
	and just focus on what you can understand.
	*/
	// Use int32_t since the user input could potentially be a very large number.
	std::int32_t x{ 0 };
	bool notInt32t = 1;
	bool cinFail{1};
	do
	{
		// Don't use an '/n' character when getting user input, it makes more sense to get it on the same line as the prompt.
		std::cout << "Enter an integer: ";
		std::cin >> x;
		cinFail = std::cin.fail();
		if (cinFail)
		{
			std::cin.clear();
			std::cin.ignore(32767, 'n');
			std::cout << "Oops, that input is invalid. This may be because you entered a number larger n";
			std::cout << "than 2147483647 (which equals 2^31-1), or less than -2147483648 (which equals -2^31); n";
			std::cout << "or you did not enter an integer only. Please try again.n";
		}
		// remove any extraneous input, which would otherwise be left in the buffer, causing unexpected results.
		else
			std::cin.ignore(32767,'n'); 
		/*Commented out because this will not work, it will fail to extract. Left in the code for education purposes.
		notInt32t = ((x > (pow(2.0, 31.0) - 1)) || (x < -pow(2.0, 31.0)) || !(x % 1 == 0));
		if (notInt32t)
			std::cout << "Oops, you entered incorrectly!n";
		*/
	} while (cinFail);
	return x;
}
bool isEven(std::int32_t x)
{
	bool isEven;
	isEven = (x % 2 == 0) ?(true):(false);
	return isEven;
}
/* I have commented this out and rewrote it, as it is ambiguous.
void printResult(bool b)
{
	std::cout << std::boolalpha;
	std::cout << b << "n";
}*/
void printIsEven()
{
	auto x = getInteger();
	if (isEven(x))
		std::cout << x << " is an even integer.n";
	else
		std::cout << x << " is an odd integer.n";
}
void printIsEvenLoop()
{
	std::int8_t yOrN{};
	bool isLoop{ true };
	bool cinFail{ false };
	bool isYOrN{ false };
	while (isLoop)
	{
		do
		{
			std::cout << "Would you like to check whether another integer is even or odd?n";
			std::cout << "Enter y or n (yes or no): ";
			std::cin >> yOrN;
			cinFail = std::cin.fail();
			if (cinFail)
			{
				std::cin.clear();
				std::cin.ignore(32767, 'n');
				std::cout << "Oops, that input is invalid! Please try again.n";
			}
			// remove any extraneous input, which would otherwise be left in the buffer, causing unexpected results.
			else
				std::cin.ignore(32767, 'n');
			isYOrN = ((yOrN == 'y' || yOrN == 'n'));
			if (!isYOrN)
				std::cout << "Oops, you entered incorrectly! Please try again.n";
		} while (cinFail || !isYOrN);
		if (yOrN == 'y')
		{
			isLoop = true;
			printIsEven();
		}
		else
			isLoop = false;
	}
	
}
int main()
{
	printIsEven();
	
	printIsEvenLoop();
	return 0;
}