hello im trying to make a random name generator but the problem is that in order to get the count of lines in the file i have to loop through it
so when i need to loop through it again in getRandomName
to get a name it has already reached the end of the file
i tried doing it with seekg(0, std::ios::beg)
but it doesnt work for some reason
int getLineCount(std::fstream &names) {
int count{};
while (names) {
std::string name;
getline(names, name);
count;
};
// last line is empty
return count - 1;
}
std::string getRandomName(std::fstream &names, int lineCount) {
int randomNum{getRandomNumber(1, lineCount)};
std::string name;
names.seekg(1, std::ios::beg); // here i try to go to the beginning but it doesnt work
for (int i{0}; i < randomNum; i) {
names >> name;
};
return name;
};
int main() {
std::srand(static_cast<unsigned int>(std::time(nullptr)));
std::rand();
std::fstream names{"names.txt"};
int lineCount{getLineCount(names)};
std::cout << getRandomName(names, lineCount);
}
CodePudding user response:
In your getLineCount()
function use while (names.peek() != EOF)
instead.
CodePudding user response:
Your getLineCount()
functions reads with getline()
through the file until it reaches the end and nothing can be read anymore. When it arrives at the end, an error state is set with eofbit
.
All subsequent actions on the stream will fail, including seekg(0, std::ios::beg)
, until you clear()
the error state:
names.clear();
If you want to do your line count properly, the best would be to get the position at the start, do your counting, clear the error state and restore the position read at the beginning.
By the way it would better to loop on getline(), as in your case you might increment the counter despite a failure to read.