Pobranie wylosowanej linii z pliku txt

0

Chciałbym pobrać 5 losowych linii z pliku questions.txt i wrzucić je do pliku enter.txt niestety nie wiem dlaczego czasami wrzuca 1 linie czasami 0 a ja chciałbym żeby zawsze to była liczba 5 linii. W pliku questions znajdują się w kolejnych wierszach liczby od 1 do 10 a plik enter jest pusty.

#include <fstream>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;

int main()
{
   fstream file;
   fstream file2;

    string line;
    int random=0;
    int numOfLines=0;
    srand(time(0));
    int num = 0;

    file.open("questions.txt");
    file2.open("enter.txt");

   while(num <= 5)
   {
        while(getline(file,line))
        {
            random = rand()%10+1;
            numOfLines++;
            if(numOfLines == random)
            {
                cout<<line<<endl;
                file2<<line<<endl;
            }
        }
    num++;
   }
   file.close();
   file2.close();


    return 0;
}
0

Bo taka jest logika zaimplementowanego kodu. Zwiększasz iterator bez względu na to co się dizeje w pętli.

0

Zmieniłem whila również na takie coś , niestety nie ma tak że zawsze wylosuje 5 linii ale bardziej to przypomina jakies losowe liczby 7,4,1,3 itp.
W pliku questions wrzucilem 1000 liczb dlatego takie losowanie.

while(getline(file,line))
        {
            int random1 = rand()%1000+1;
            int random2 = rand()%1000+1;
            int random3 = rand()%1000+1;
            int random4 = rand()%1000+1;
            int random5 = rand()%1000+1;
            numOfLines++;
            if(numOfLines == random1 || numOfLines == random2 || numOfLines == random3 || numOfLines == random4 || numOfLines == random5)
            {
                cout<<line<<endl;
                file2<<line<<endl;

            }
        }
0
while (num < 5)
	{		
		file.open("questions.txt");
		int random = rand() % 10 + 1;
		numOfLines = 0;
		while (getline(file, line))
		{			
			if (numOfLines == random)
			{
				file2 << line << endl;	
				file.close();
				break;		
			}
			numOfLines++;
		}
			num++;		
	}

W ten sposób zapisuje 5 losowych linii. Otwieranie i zamykanie pliku na nowo jest dodane, ponieważ po wpisaniu pierwszej linii do pliku druga pętla while przeszukiwanie zaczyna od tej na której skończyła poprzednio, ekspertem nie jestem, więc domyślam się, że istnieje lepsze rozwiązanie z ominięciem powtarzania zamykania i otwierania.

1
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <string>
using namespace std;

int main()
{
	fstream file;
	fstream file2;
	string line;
	int numOfLines;
	srand(time(0));
	int num = 0;
	file2.open("enter.txt");
	while (num < 5)
	{		
		file.open("questions.txt");
		int random = rand() % 10 + 1;
		numOfLines = 0;
		while (getline(file, line))
		{			
			if (numOfLines == random)
			{
				file2 << line << endl;	
				file.close();
				break;		
			}
			numOfLines++;
		}
			num++;		
	}
	file2.close();
	system("pause");
	return 0;
}

Wrzucam cały kod, może gdzieś indziej coś zmieniłem jeszcze. U mnie zapisuje 5 losowych linii.

EDIT: Teraz widzę, że czasami losuje więcej niż 5 linii, ale to raczej drobna poprawka będzie.

1
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
 
using namespace std;
 
using Questions = vector<string>;
using QuestionnaireResult = vector<pair<string, string>>;
 
Questions  readAllLines(istream &input) {
   Questions  result;
 
    string line;
    while (getline(input, line)) {
        result.push_back(line);
    }
    return result;
}
 
Questions readAllLinesFromFile(const string &fileName) {
    ifstream file(fileName);
    return readAllLines(file);
}
 
QuestionnaireResult askRandomQuestions(const vector<string> &questions,
                                       size_t n,
                                       ostream &output,
                                       istream &input) {
   QuestionnaireResult result;
 
    for (size_t i = 0; i < n; ++i) {
          int questionNr = rand() % questions.size();
          auto question = questions[questionNr];
          string answear;
          output << (i + 1) << " (" << questionNr << "): " << question << '\n';
          if (getline(input, answear)) {
                result.emplace_back(question, answear);
          }
    }
    return result;
}
 
void printQuestionnaire(const QuestionnaireResult &questionnaire, ostream &out) {
    for (const auto &questionAnswear : questionnaire) {
          out << questionAnswear.first << '\n';
          out << questionAnswear.second << '\n';
    }
}
 
void writeQuestionnaireToFile(const QuestionnaireResult &questionnaire, const string &fileName) {
    std::ofstream file(fileName);
    printQuestionnaire(questionnaire, file);
}
 
int main()
{
    srand(time(0));
    auto questions = readAllLinesFromFile("questions.txt");
    auto answears = askRandomQuestions(questions, 5, cout, cin);
    writeQuestionnaireToFile(answears, "enter.txt");
    printQuestionnaire(answears, cout);
 
    return 0;
}
0

Najprościej to chyba wczytać linie do wektora, użyć std::shuffle i obciąć wektor do pięciu elementów.

std::vector< int > numbs;
std::ifstream input_file( "questions.txt" );
std::copy( std::istream_iterator< int >( input_file ), std::istream_iterator< int >(), std::back_inserter( numbs ) );
std::random_device rd;
std::mt19937 rng( rd () );
std::shuffle( numbs.begin(), numbs.end(), rng );
numbs.resize( 5 );
std::ofstream output_file( "enter.txt" );
std::copy( numbs.begin(), numbs.end(), std::ostream_iterator< int >( output_file, "\n" ) );

1 użytkowników online, w tym zalogowanych: 0, gości: 1