【问题标题】:How to fetch information randomly from files in C++?如何从 C++ 中的文件中随机获取信息?
【发布时间】:2015-07-31 12:14:37
【问题描述】:

我正在用 C++ 创建一个问答游戏。因此,主要要求是每次程序运行时都应从文件中随机获取问题。那么,我怎样才能在 C++ 中做到这一点? 考虑以下两个简单的程序。

Write.cpp

#include <iostream>
#include <fstream>
#include <string>
using std::cout;
using std::ofstream;
using std::string;
int main()
{
    ofstream fout("test.txt");
    if(!fout)
        cout<<"Error in opening file";
    string s[3];
    s[0]="C++ provides object oriented string handling";
    s[1]="C++ provides object oriented exception handling";
    s[2]="C++ provides highest flexibility to the programmer";
    for(int i=0;i<3;i++)
        fout<<s[i]<<'\n';
    fout.close();
}

读取.cpp

#include <iostream>
#include <fstream>
#include <string>
using std::cout;
using std::string;
using std::ifstream;
int main()
{
    ifstream fin("test.txt");
    if(!fin)
        cout<<"Error in opening file";
    string s[3];
    for(int i=0;i<3;i++)
        getline(fin,s[i]);
    for(int i=0;i<3;i++)
        cout<<s[i]<<'\n';
    fin.close();
}

我应该怎么做,当我编译 Read.cpp 并运行 Read.exe 文件时,应该从文件中随机获取 3 个字符串并显示出来?

非常感谢您的帮助。

【问题讨论】:

  • 您能否添加有关您的问题的更多详细信息?你试过什么?
  • @Ilya:我已经提供了有关我的问题的足够详细信息。你还需要什么?
  • 如果文件的每一行都是一个可能的目标字符串,并且你知道文件中的总行数,你可以从1 .. line_count范围内生成3个随机数,然后遍历你的文件并存储每个随机生成的数字对应的每一行
  • @Ploutox:如果你写一个答案并使用程序解释它会更好。
  • @PravasiMeet,现在还不明显,你有算法或技术问题吗。您是否需要描述可以以随机顺序显示数组字符串的算法?或者您是否需要有关如何在 c++ 中获取随机值的信息?

标签: c++ file ifstream information-retrieval ofstream


【解决方案1】:

如果您想按照从文件中读取的顺序维护字符串数组

您可以通过创建另一个包含数字 [1, 2 .. n-1] 的整数数组(其中 n 是字符串的数量)然后对其进行改组以获得随机的索引序列来实现这一点,您可以用于打印字符串。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>

using std::cout;
using std::string;
using std::ifstream;

int main()
{
    ifstream fin("test.txt");
    if(!fin)
        cout<<"Error in opening file";

    std::vector<string> lines;
    string line;
    while (getline(fin, line))
          lines.push_back(line);

    // Create a std::vector containing {1, 2 .. n-1} 
    // and shuffle it to obtain a random ordering.
    std::vector<int> order;
    for (int i = 0; i < lines.size(); ++i)
    {
       order.push_back(i);
    }

    // C++11
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // Seed from current time.
    auto engine = std::default_random_engine{seed}; // You may also want to look into uniform_int_distribution.
    std::shuffle(std::begin(order), std::end(order), engine);

    // C++98
    // std::random_shuffle(order.begin(), order.end());

    // Prints strings in random order.
    for (int number : order)
         cout << lines[number] <<'\n';

    fin.close();
}

如果可以修改(shuffle)字符串数组

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>

using std::cout;
using std::string;
using std::ifstream;

int main()
{
    ifstream fin("test.txt");
    if(!fin)
        cout<<"Error in opening file";

    std::vector<string> lines;
    string line;
    while (getline(fin, line))
          lines.push_back(line);

    // C++11
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // Seed from current time.
    auto engine = std::default_random_engine{seed}; // You may also want to look into uniform_int_distribution.
    std::shuffle(std::begin(lines), std::end(lines), engine);

    // C++98
    // std::random_shuffle(lines.begin(), lines.end());

    // Prints strings in random order.
    for (string& line : lines)
         cout << line <<'\n';

    fin.close();
}

Try it online!

【讨论】:

  • 我尝试了您的解决方案,但每次都得到相同的输出。看起来字符串没有随机显示。
  • 如果您使用的是 c++ 11 标准,请考虑使用shuffle 而不是random_shuffle
  • 添加了带有shuffle的C+11版本,这比random_shuffle更加随机
  • @PravasiMeet 我添加了从当前时间获得的种子。请试一试。我还添加了一个可以在线测试的 sn-p 的链接。
  • @Nishant 在没有明确提供种子的情况下,default_random_engine 使用默认种子。所以确实它会生成相同的数字序列(我一开始忽略了它)。
【解决方案2】:

最简单的解决方案是将你的行放入std::list,然后使用std::random_shuffle随机重新排序:

#include <algorithm>    // std::random_shuffle
#include <list>         // std::list
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand
std::list<std::string> str_list;
std::string buf_str;

for(int i=0;i<3;i++){
  getline(fin,buf_str);
  str_list.push_back(buf_str);
}
std::srand(std::time(0));
std::random_shuffle ( str_list.begin(), str_list.end() );
// then just print lines from str_list

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2016-07-15
    • 2019-08-16
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多