Я новичок в C ++ и выполнял упражнение, найденное здесь:

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

Я проводил викторину 2, в которой говорится, что я должен создать программу, которая получает целое число от пользователя и выводит истинное значение этого целого числа. Итак, я создал следующий код:

#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. Почему это происходит ?

c++
0
Nelson Tethers 20 Апр 2016 в 21:00

4 ответа

Лучший ответ

У вас есть следующий код:

int8_t x;
std::cin >> x;

int8_t - это просто псевдоним для char для вашей платформы и std::istream, когда он имеет тип char в качестве входного аргумента одного символа, а не целого числа. Таким образом, решением было бы использовать тип int, и вы должны использовать его с самого начала, поскольку в этом случае нет никакой причины использовать int8_t.

2
Slava 20 Апр 2016 в 18:07

Эта функция возвращает тип, отличный от того, который должен был возвращать:

int getInteger()
{
    std::cout << "Insert an integer" << "\n";

    int8_t x;

    std::cin >> x;

    return x;
}

int должен работать нормально вместо int8_t. Узнайте, почему Документация

1
Community 23 Май 2017 в 12:09

Как у вас есть, 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();
0
πάντα ῥεῖ 20 Апр 2016 в 18:12

Причина, по которой Алекс на learncpp.com указывает, что лучше использовать целые числа фиксированной ширины, заключается в том, что результаты программы не будут отличаться при ее компиляции на разных компиляторах. Это не относится к целочисленным типам нефиксированной ширины, таким как char и int, поскольку размер типа будет варьироваться в зависимости от компилятора. Как указывает @Slava, int8_t является целочисленным типом фиксированной ширины для char, поэтому оба используются с переменными, которые сохраняют в памяти только один символ.

Используйте целые числа фиксированной ширины, когда программу можно использовать в другом компиляторе или другом компьютере, и важно, чтобы результаты не зависели от компилятора и платформы. Поскольку программа запрашивает ввод любого целого числа, для использования целого числа фиксированной ширины было бы лучше использовать int32_t. int8_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 и 2147 483 647).

Как Алекс объясняет позже в 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;
}
0
James Ray 17 Апр 2017 в 04:05