1

I want to do is basically writing a function which takes a parameter as a file name and if have multiple files, it will just take file name as a parameter and it should do this repetitively with a function. How can i do this? Thanks.

Txt files are like this for example, sorular.txt:

//What is the most crowded country in the world?
//China
//USA
//Germany
//Australia
//China

int main (){

    string array [5];
    string line;
    string answer;
    static int trueCount = 0;
    static int falseCount = 0;
    ifstream file("/Users/User/QuizMaker/Quiz Maker V2/sorular.txt");

    if(file.is_open()){
        cout << "Questions are loading... Please wait.."<<endl<<" ."<<endl<<" ."<<endl<<" ."<<endl;
        while (!file.eof()) {
            for (int i = 0; i<6; i++) {
                getline(file,array[i]);
            }

            for (int a = 0; a<5; a++) {
                  cout << array[a] << endl;
            }
            cin >> answer;

            if(answer == "C" || answer == "c") {
                cout << true;
                trueCount++;
            }
            else falseCount++;
        }

        cout << "You answered "<<trueCount << " questions as true" << endl;
        cout << "You answered "<<falseCount << " questions as false" << endl;
        file.close();
    } else cout << " not ıoen";

    cin.get();

    return 0;
}
Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241
  • Sure, you can accept arguments from the command line. The `argc` and `argv` of `main(int argc, char** argv)` fame are the route to those arguments. – Niall May 12 '16 at 09:34
  • 1
    [Incidentally](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – user657267 May 12 '16 at 09:35
  • 2
    Do you ask how to write a function which takes `std::string` as a parameter? I feel like there's nothing I can help you with. You should just learn the very basics. – Lukáš Bednařík May 12 '16 at 09:37
  • Thank you very much for your advices. I am actually learning them too. But, in one of the projects, i need to do this kind of stuff. What is your solution for this question? Where am i really missing out? thanks @specializt – oguzdumanoglu May 12 '16 at 09:37
  • Your `.eof()` is completely ineffective. Did you expect it to kick in midway through an iteration? – Lightness Races in Orbit May 12 '16 at 09:53
  • 1
    @oguzdumanoglu: Please disregard the advice from specializt. In C++, pointers aren't that important. For arrays, there's `std::array` instead of the array type `std::string[5]` which you have now. – MSalters May 12 '16 at 13:40

1 Answers1

1

First let me say, that array cannot hold elements 0, 1, 2, 3, 4, and 5. It has only allocated 5 elements.


This may stretch your horizons a bit, but I think the right solution is a class here. So i'm going to hack this together, if you're interested you can research what I've done a bit and if you don't understand something feel free to ask in a comment.

class foo : public iterator<input_iterator_tag, string> {
    const initializer_list<const char*> _files;
    decltype(_files)::const_iterator _filesIt;
    ifstream _file;
    string _line;

    void get() {
        string array[6];
        auto i = begin(array);

        while (i != end(array) && getline(_file, *i)) {
            advance(i, 1);
        }

        if (i == end(array)) {
            _line = accumulate(cbegin(array), cend(array), string(), [](const auto& a, const auto& b) { return a.empty() ? b : a + '\n' + b; });
        } else if(++_filesIt != cend(_files)) {
            _file.close();
            _file.open(*_filesIt);
            get();
        }
    }
public:
    foo() : _filesIt(cend(_files)) {}
    foo(foo& rhs) : _files(rhs._files), _filesIt(next(cbegin(_files), distance(cbegin(rhs._files), rhs._filesIt))), _line(rhs._line) {
        if (_filesIt != cend(_files)) {
            _file.open(*_filesIt);
            _file.seekg(rhs._file.tellg());
        }
    }
    foo(const initializer_list<const char*>&& files) : _files(files), _filesIt(cbegin(_files)), _file(*_filesIt) { get(); }
    const string& operator*() const { return _line; }
    const foo& operator++() {
        get(); 
        return *this;
    }
    const foo operator++(int) {
        foo result;

        get();
        return result;
    }
    bool operator==(const foo& rhs) { return distance(_filesIt, cend(_files)) == distance(rhs._filesIt, cend(rhs._files)); }
    bool operator!=(const foo& rhs) { return distance(_filesIt, cend(_files)) != distance(rhs._filesIt, cend(rhs._files)); }
};

Though this class may seem overwhelming it greatly simplifies the rest of what you're trying to acompilsh. With this class the rest of your code will read:

auto true_count = 0;
auto false_count = 0;

for_each(foo({"/Users/User/QuizMaker/Quiz Maker V2/sorular.txt", "foo.txt", "bar.txt"}), foo(), [&](const auto& i) {
    string answer;

    cout << i << endl;
    cin >> answer;

    if(answer == "C" || answer == "c") {
        cout << 1;
        true_count++;
    } else {
        false_count++;
    }
});
cout << "You answered "<< trueCount << " questions as true" << endl << "You answered " << falseCount << " questions as false" << endl;
Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241