I'm translating a python function into a C++ function; this function uses a yield(string)
statement that I don't know how to translate.
Here the whole story...I have a certain function that reads an input ASCII file filename
, which contains lines of data, and puts the content of the file into an std::vector
. When reading this input file (in another function respect with the one showed below), I need to jump a bunch of lines (5 or 6, it depends on the input file's name) and, for this purpose, I define a function, the file_struct_generator
, which marks as "data" the data lines and as "unused" the data lines I don't need. I need something similar to this function in C++, and in particular, I need something similar to yield(string)
(pay attention, string
!), but in C++ of course. Here I show you the lines of the code I need to "translate" from python to C++. How can I rewrite yield("unused")
and yield("data")
in C++? Or if yield
is unusable in C++, can I write a similar function in C++ using something different which works as a generator? Thanks for helping me!
def file_struct_generator(filename):
if "more" in filename:
bad_line_number = 5
else:
bad_line_number = 6
yield("data")
for i in range(bad_line_number):
yield("unused")
while True:
yield("data")
EDIT: I do not use C++20, but C++11. I tried @Arthur Tacca code and it works for my purpose, thank you all.
This is a state machine that reproduces that generator's functionality.
#include <stdexcept>
#include <string>
#include <iostream>
class FileStructIterator {
public:
explicit FileStructIterator(const std::string& filename):
m_filename(filename), m_state(STATE_START)
{}
std::string getNext() {
switch (m_state) {
case STATE_START:
m_state = STATE_LOOP1;
if (m_filename.find("more") != std::string::npos) {
m_badLineNumber = 5;
} else {
m_badLineNumber = 6;
}
m_i = 0;
return "data";
case STATE_LOOP1:
++m_i;
if (m_i >= m_badLineNumber) {
m_state = STATE_LOOP2;
}
return "unused";
case STATE_LOOP2:
return "data";
default:
throw std::logic_error("bad state");
}
}
private:
std::string m_filename;
enum State { STATE_START, STATE_LOOP1, STATE_LOOP2 };
State m_state;
size_t m_badLineNumber;
size_t m_i;
};
Here's an example of using it (in this case I limited the output to the first 10 results so it doesn't loop forever).
int main() {
auto it = FileStructIterator("nomore.txt");
for (int i = 0; i < 10; ++i) {
std::string nextValue = it.getNext();
std::cout << nextValue << "\n";
}
}