我做了一个小程序,生成素数,让用户检查一个数字,看看它是不是素数.问题是,我不确定如何正确设计它.这是该计划:
#include <iostream>
#include <vector>
typedef unsigned long long bigint;
std::vector<bool> sieve(size_t size)
{
std::vector<bool> primelist(size);
primelist[0] = false;
primelist[1] = false;
for (bigint i = 2; i < size; ++i) { primelist[i] = true; }
for (bigint i = 2; i * i < size; ++i)
{
if (primelist[i])
{
for (bigint j = i; j * i < size; ++j)
primelist[i*j] = false;
}
}
return primelist;
}
int main()
{
bigint range;
bigint number;
std::vector<bool> primes;
std::cout << "Enter range: " << std::endl;
std::cin >> range;
primes = sieve(range);
while (1)
{
std::cout << "Enter number to check: " << std::endl;
std::cin >> number;
if (primes[number])
std::cout << "Prime" << std::endl;
else
std::cout << "Not prime" << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的基本流程是:输入范围,/句柄输入/,要检查的输入数,/句柄输入/
我还希望通过编写"更改范围编号 "之类的命令,为用户提供在任何给定时间更改范围的选项
我有一些问题:
如果用户输入大于无符号long long的范围,并且如果用户基本上超过任何限制(例如,如果他输入的范围是100然后如果他检查101),我希望程序受到控制,异常将是抓住.我知道这需要使用try/catch/throw来实现,但是我不知道如何在保持选项更改范围的同时不使用我的代码spaghetti代码.
此外,我希望错误是枚举类型(我读到枚举适用于异常),类似于
enum errors
{
OUT_OF_RANGE = 1, //Out of the range specified by the user
INCORRECT_VALUE, //If user input "one" instead of 1
RANGE_SIGNED, //If user inputs a signed value for range
NUM_LIMITS //Number exceeds unsigned long long
};
Run Code Online (Sandbox Code Playgroud)
我不知道如何使用异常处理,更不用说使用枚举.我该如何保持这个程序的安全和运行,同时远离意大利面条代码?
我非常困惑.如果有人可以帮我正确设计这个程序并保持可读性和效率,它将真正改善我未来的程序设计.
谢谢阅读!
你问了很多。
您想要验证用户输入。用户不应该能够输入巨大的数字、非整数等。
我首先要回答的是,这绝对不是应该使用异常的场景。异常用于处理异常情况。这些是你无法预料或真正处理的。
用户输入的数字太大?你可以处理的。告诉他们他们的数字太大,请输入 1 到 X 之间的数字。
用户输入单词“apple”?你可以处理的。告诉他们只能输入整数。
做到这一点的一种方法是创建一个ValidateInput函数。您可以让它返回一个数字(或枚举,它们基本上是相同的东西)来告诉您是否存在错误。
为了进行验证,您很可能必须接收输入std::string,然后在将其转换为数字之前对其进行验证。以整数类型或类似的整数类型获取输入unsigned int实际上并不能让您检查错误。
这增加了一些工作,因为您需要手动验证输入。有一些库提供了可以帮助解决此问题的函数,例如boost::lexical_cast,但现在对您来说可能太多了。
下面是一些非常基本的伪代码来说明我的意思。它只是为了让您知道要做什么,它不会为您编译或完成工作。您可以通过创建一个基于错误代码等返回消息的通用函数来进一步扩展它。
enum error_code {
SUCCESS, // No error
OUT_OF_RANGE, // Out of the range specified by the user
INCORRECT_VALUE, // If user input "one" instead of 1
RANGE_SIGNED, // If user inputs a signed value for range
NUM_LIMITS // Number exceeds unsigned long long
};
// This function will check if the input is valid.
// If it's not valid, it will return an error code to explain why it's invalid.
error_code ValidateInput(const std::string& input) {
// Check if input is too large for an unsigned long long
if (InputIsTooLarge)
return NUM_LIMITS;
// Check if input is negative
if (InputIsNegative)
return RANGE_SIGNED;
// Check if input is not an integer
if (InputIsNotInteger)
return INCORRECT_VALUE;
// If we make it here, no problems were found, input is okay.
return SUCCESS;
}
unsigned long long GetInput() {
// Get the user's input
std::string input;
std::cin >> input;
// Check if the input is valid
error_code inputError = ValidateInput(input);
// If input is not valid, explain the problem to the user.
if (inputError != SUCCESS) {
if (inputError == NUM_LIMITS) {
std::cout << "That number is too big, please enter a number between "
"1 and X." << std::endl;
}
else if (inputError == RANGE_SIGNED) {
std::cout << "Please enter a positive number." << std::endl;
}
else if (inputError == INCORRECT_VALUE) {
std::cout << "Please enter an integer." << std::endl;
}
else {
std::cout << "Invalid input, please try again." << std::endl;
}
// Ask for input again
return GetInput();
}
// If ValidateInput returned SUCCESS, the input is okay.
// We can turn it into an integer and return it.
else {
return TurnStringIntoBigInt(input);
}
}
int main() {
// Get the input from the user
unsigned long long number = GetInput();
// Do something with the input
}
Run Code Online (Sandbox Code Playgroud)