C++ 选择4个随机数printf

C++ 选择4个随机数printf,c++,printf,cout,C++,Printf,Cout,所以,我的代码有问题。程序需要从4个printf中随机选择一个并在终端中打印。我是新来的,对此我很抱歉 #include <stdio.h> #include <stdlib.h> #include <locale.h> int main () { setlocale (LC_ALL, "Portuguese"); int opcao; opcao = rand() % 3 + 1; if (opcao == 0) {

所以,我的代码有问题。程序需要从4个printf中随机选择一个并在终端中打印。我是新来的,对此我很抱歉

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main () {
    setlocale (LC_ALL, "Portuguese");
    int opcao;
    opcao = rand() % 3 + 1;

    if (opcao == 0) {
        printf ("\nA opção sorteada foi a de que o 1º classificado atual será o campeão (FC Porto)");
    }

    if (opcao == 1) {
        printf ("\nA opção sorteada foi a de que o 1º classificado na 1ª volta será o campeão (SL Benfica)");
    }

    if (opcao == 2) {
        printf ("\nA opção sorteada foi a de que Porto e Benfica farão um jogo em campo neutro para determinar o campeão!");
    }

    if (opcao == 4) {
        printf ("\nFoi sorteada a opção de que não haverá campeão esta época");
    } 


    return 0;
}

这是我的代码,但只是不断地选择相同的printf。

您没有为随机数生成器提供种子。从手册页

如果未提供种子值,则会自动为函数设定种子 值为1


如果每次运行都有相同的种子,则始终会得到相同的随机序列。

您没有为随机数生成器提供种子。从手册页

如果未提供种子值,则会自动为函数设定种子 值为1


如果你每次跑步都有相同的种子,你总是会得到相同的随机序列。

你的程序有几个问题:

你没有种子,这就是数字重复的原因。使用
您的程序有几个问题:

你没有种子,这就是数字重复的原因。使用
我想在这里补充一些东西,补充前面的答案

首先也是最重要的是,您并不是在为自己编写代码。作为一个非英语母语的人,我理解为什么用你的母语写代码似乎更容易,但不要这样做

其次,我对代码进行了更改,以使其更容易阅读:

#include <time.h>
#include <cstdint>
#include <iostream>
#include <string>

constexpr uint32_t NUM_OF_POSSIBLE_PROMPTS = 4;

int main () {
    srand(time(NULL)); // seed according to current time

    for (uint32_t i = 0; i < 10; ++i)
    {
        int option = rand() % (NUM_OF_POSSIBLE_PROMPTS);

        std::string prompt = "";

        switch (option)
        {
            case 0:
                prompt = "option 0";
                break;
            case 1:
                prompt = "option 1";
                break;
            case 2:
                prompt = "option 2";
                break;
            case 3:
                prompt = "option 3";
                break;
            default:
                // some error handling!
                break;
        }

        std::cout << prompt << std::endl;
    }

    return 0;
}
我使用的是switch case,而不是if-else,它更具可读性和效率

我使用constexpr来存储我的硬编码数字——在实际程序的代码中使用硬编码数字是一个坏习惯,对于循环边界,我会将constexpr值设置为10


< C++ >与C不同,我们使用STD::CUT及其操作符

,我想在这里添加一些东西,添加到前面的答案。

首先也是最重要的是,您并不是在为自己编写代码。作为一个非英语母语的人,我理解为什么用你的母语写代码似乎更容易,但不要这样做

其次,我对代码进行了更改,以使其更容易阅读:

#include <time.h>
#include <cstdint>
#include <iostream>
#include <string>

constexpr uint32_t NUM_OF_POSSIBLE_PROMPTS = 4;

int main () {
    srand(time(NULL)); // seed according to current time

    for (uint32_t i = 0; i < 10; ++i)
    {
        int option = rand() % (NUM_OF_POSSIBLE_PROMPTS);

        std::string prompt = "";

        switch (option)
        {
            case 0:
                prompt = "option 0";
                break;
            case 1:
                prompt = "option 1";
                break;
            case 2:
                prompt = "option 2";
                break;
            case 3:
                prompt = "option 3";
                break;
            default:
                // some error handling!
                break;
        }

        std::cout << prompt << std::endl;
    }

    return 0;
}
我使用的是switch case,而不是if-else,它更具可读性和效率

我使用constexpr来存储我的硬编码数字——在实际程序的代码中使用硬编码数字是一个坏习惯,对于循环边界,我会将constexpr值设置为10

在C++中,与C++不同,我们使用STD::CUT及其操作符

使用库而不是过时的、易出错的STD::Rand,使用模算符来获得范围内的随机整数。有关更多信息,请参阅

#include <iostream>
#include <random>

int main()
{
    std::mt19937 engine{std::random_device{}()};
    std::uniform_int_distribution<int> dist{0, 3};

    switch (dist(eng)) {
    case 0:
        std::cout << "...\n";
        break;
    case 1:
        std::cout << "...\n";
        break;
    case 2:
        std::cout << "...\n";
        break;
    case 3:
        std::cout << "...\n";
        break;
    }
}
这里,我们使用和来支持从任意随机可访问范围中选择元素并对其执行任意操作

首先,我们检查范围是否为空,在这种情况下,无法进行选择,并通过调用报告错误

然后,我们创建一个std::mt19937引擎,也就是说,每个线程都有自己的引擎来阻止。引擎的状态在调用之间保持,因此我们只为每个线程种子一次

然后,我们创建一个std::uniform_int_分布来生成一个随机索引。请注意,我们使用了long long而不是:std::uniform_int_分布仅保证与short、int、long、long long、unsigned short、unsigned int、unsigned long和unsigned long long一起使用,因此如果difference_类型是有符号字符或扩展有符号整数类型,则会导致未定义的行为。long-long是受支持的最大有符号整数类型,我们使用它来防止

最后,我们将调用可调用对象,并将其与所选元素一起使用。说明符确保保留调用的类型和类型

我们使用和调用函数来打印所选元素

从C++20开始,我们可以使用以下概念约束函数模板:

template <std::random_access_iterator RanIt,
          std::indirectly_­unary_­invocable<RanIt> F>
decltype(auto) select(RanIt begin, RanIt end, F&& f)
{
    // ...
}
在C++20之前,我们还可以使用SFINAE:

template <typename RanIt, typename F>
std::enable_if_t<
    std::is_base_of_v<
        std::random_access_iterator_tag,
        typename std::iterator_traits<RanIt>::iterator_category
    >,
    std::invoke_result_t<F, typename std::iterator_traits<RanIt>::value_type>
> select(RanIt begin, RanIt end, F&& f)
{
    // ...
}
使用库而不是过时且容易出错的std::rand使用模运算符获取范围为的随机整数。有关更多信息,请参阅

#include <iostream>
#include <random>

int main()
{
    std::mt19937 engine{std::random_device{}()};
    std::uniform_int_distribution<int> dist{0, 3};

    switch (dist(eng)) {
    case 0:
        std::cout << "...\n";
        break;
    case 1:
        std::cout << "...\n";
        break;
    case 2:
        std::cout << "...\n";
        break;
    case 3:
        std::cout << "...\n";
        break;
    }
}
这里,我们使用和来支持从任意随机可访问范围中选择元素并对其执行任意操作

首先,我们检查范围是否为空,在这种情况下,无法进行选择,并通过调用报告错误

然后,我们创建一个std::mt19937引擎,也就是说,每个线程都有自己的引擎来阻止。引擎的状态在调用之间保持,因此我们只为每个线程种子一次

然后,我们创建一个std::uniform_int_分布来生成一个随机索引。注意,我们使用了long-long而不是:std::uniform_int_分布仅保证与short、int、long、long-long、unsigned short、unsigned int、unsigned long和unsigned long-long一起使用,因此如果差分_类型是signed char或ex 如果是有符号整数类型,则会导致未定义的行为。long-long是受支持的最大有符号整数类型,我们使用它来防止

最后,我们将调用可调用对象,并将其与所选元素一起使用。说明符确保保留调用的类型和类型

我们使用和调用函数来打印所选元素

从C++20开始,我们可以使用以下概念约束函数模板:

template <std::random_access_iterator RanIt,
          std::indirectly_­unary_­invocable<RanIt> F>
decltype(auto) select(RanIt begin, RanIt end, F&& f)
{
    // ...
}
在C++20之前,我们还可以使用SFINAE:

template <typename RanIt, typename F>
std::enable_if_t<
    std::is_base_of_v<
        std::random_access_iterator_tag,
        typename std::iterator_traits<RanIt>::iterator_category
    >,
    std::invoke_result_t<F, typename std::iterator_traits<RanIt>::value_type>
> select(RanIt begin, RanIt end, F&& f)
{
    // ...
}

在使用rand之前使用srand。请注意此表达式opcao=rand%3+1;永远不等于0。您应该使用opcao=rand%4;尽管这仍然不能处理以下情况:如果opcao==4rand,则%5将返回值0-4。模运算符的结果,例如,v=rand%n时的百分比;始终为0。在使用rand之前,某些其他表达式可能有助于使用srand。请注意,此表达式opcao=rand%3+1;永远不等于0。您应该使用opcao=rand%4;尽管这仍然不能处理以下情况:如果opcao==4rand,则%5将返回值0-4。模运算符的结果,例如,v=rand%n时的百分比;总是0的一些ELSE可以帮助Toice使用现代C++。虽然它没有指出原始问题中的直接错误,但这是如何使用标准库的一个非常好的示例。实际上,使用新的随机库更好!我想为第二个示例添加更多的解释,因为它不是很容易理解,特别是对于提出问题的用户。@Kerek我添加了一些解释和一系列链接。现在好多了?太好了谢谢你的澄清!这里使用的是现代C++。虽然它没有指出原始问题中的直接错误,但这是如何使用标准库的一个非常好的示例。实际上,使用新的随机库更好!我想为第二个示例添加更多的解释,因为它不是很容易理解,特别是对于提出问题的用户。@Kerek我添加了一些解释和一系列链接。现在好多了?太好了谢谢你的澄清!