Search code examples
c++fstream

Reading an input file in C++


I want to read an input file in C++ which includes the following lines

- numberOfStates
- numberOfSymbols
- numberOfFinalStates
- list of final states (one per line)
- numberOfTransitions
- listOfTransitions (one per line. The transitions include two ints and one char)

It's important to say that the numbers are different in each input file. I have to read a different amount of lines for each file.

This is an example inputFile

10 
3 
1 
9 
12 
0 1 f 
0 3 f 
1 2 a 
2 9 f 
3 4 f 
3 8 f 
4 5 b 
5 6 f 
6 7 a 
8 9 f 

How can I declare each variable while reading the input file?

This is where I'm stuck.. don't really know what to do

ifstream fin("inputFile.txt");

    int numberOfStates;
    int numberOfSymbols;
    int numberOfFinalStates;
    // I'm not sure how to declare the next variables because they will vary in size each time 


    while (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates)
    {
        cout << numberOfStates << numberOfSymbols << numberOfFinalStates << endl;
    }

I'd like to work with vectors if possible.


Solution

  • doing

    while (fin >> name >> var1 >> var2 >> var3)
    {
        cout << name << var1 << var2 << var3 << endl;
    }
    

    you rewrite all the time on the same variables, you need to put the value in a vector as you say in your question

    you need also to check if each input is correct, currently you do not detect the invalid input

    and of course you need to check you open the file


    Example :

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    int main()
    {
      std::ifstream fin("inputFile.txt");
    
      if (!fin.is_open()) {
        std::cerr << "cannot open inputFile.txt" << std::endl;
        return -1;
      }
    
      int numberOfStates, numberOfSymbols, numberOfFinalStates;
    
      if ((! (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates))
          || (numberOfStates < 0)
          || (numberOfSymbols < 0)
          || (numberOfFinalStates < 0)) {
        std::cerr << "invalid file" << std::endl;
        return -1;
      }
    
      // final states are int, so memorize them in a vector of int
      // because their number is known I can size it rather than 
      // to 'push_back' each value
      std::vector<int> finalStates(numberOfFinalStates);
    
      for (int & ft : finalStates) {
        if (! (fin >> ft)) {
          std::cerr << "invalid file reading final states" << std::endl;
          return -1;
        }
      }
    
      int numberOfTransitions;
    
      if (!(fin >> numberOfTransitions) || (numberOfTransitions < 0))  {
        std::cerr << "invalid file reading the number of transitions" << std::endl;
        return -1;
      }
    
      // you say a transition contains 2 int and a char,
      // I define a structure for
      // i1 i2 and c are 'poor' names but I don't know their goal
      struct Transition {
        int i1, i2; 
        char c;
      };
    
      // the transitions saved in a vector
      std::vector<Transition> transitions(numberOfTransitions);
    
      for (Transition & tr : transitions) {
        if (!(fin >> tr.i1 >> tr.i2 >> tr.c)) {
          std::cerr << "invalid file reading transitions" << std::endl;
          return -1;
        }
      }
    
      // print to check
    
      std::cout << "numberOfStates=" << numberOfStates << std::endl;
      std::cout << "numberOfSymbols=" << numberOfSymbols << std::endl;
      std::cout << "numberOfFinalStates=" << numberOfFinalStates << "\nfinalStates:";
      for (int ft : finalStates) 
         std::cout << ' ' << ft;
      std::cout << std::endl;
      std::cout << "numberOfTransitions=" << numberOfTransitions
        << "\ntransitions:" << std::endl;
      for (const Transition & tr : transitions)
        std::cout << '\t' << tr.i1 << ' ' << tr.i2 << ' ' << tr.c << std::endl;
    
      return 0;
    }
    

    Compilation and execution :

    pi@raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall a.cc
    pi@raspberrypi:/tmp $ cat inputFile.txt
    10 
    3 
    1 
    9 
    12 
    0 1 f 
    0 3 f 
    1 2 a 
    2 9 f 
    3 4 f 
    3 8 f 
    4 5 b 
    5 6 f 
    6 7 a 
    8 9 f 
    pi@raspberrypi:/tmp $ ./a.out
    invalid file reading transitions
    

    The error comes because the file contains only 10 transitions rather than 12 expected, modifying the file to expect 10 transitions :

    pi@raspberrypi:/tmp $ ./a.out
    numberOfStates=10
    numberOfSymbols=3
    numberOfFinalStates=1
    finalStates: 9
    numberOfTransitions=10
    transitions:
        0 1 f
        0 3 f
        1 2 a
        2 9 f
        3 4 f
        3 8 f
        4 5 b
        5 6 f
        6 7 a
        8 9 f
    pi@raspberrypi:/tmp $