Search code examples
c++readfile

How to read multiple files on C++


My problem is :

First read a file named symbols.txt. This file consist of many lines, each line consist of 2 elements : an uppercase letter and a string, this file is ended by a hash(#).

Second read a file named dict.txt. This file consist of many words(string) . Ended by a hash(#)

Third read a file named handin.txt. This file consist of some numbers which you're gonna working on it. Ended by a hash(#)

Print your output in a file named handout.txt

This is my code but I'm not sure that I let in read the input right. Please check it for me. Thanks a lot.

#include<bits/stdc++.h>
using namespace std;

int main() {

    freopen("symbols.txt" , "r" , stdin);

         //  input the letter and the string 

    char X ; string Y ;

    while(cin >> X >> Y && X != '#' )  {
         // my code goes here
    }

    freopen("dict.txt" , "r" , stdin) ;

          // input the strings here 

    freopen("handin.txt", "r" , stdin);

         // input the numbers here


    / *

          Here is my code 

    * /

    freopen("handout.txt" , "w" , stdout);

    // let in print the output here



}

Solution

  • #include<bits/stdc++.h>
    

    Don't do this. Here's why


    using namespace std;
    

    Don't do this either. Here's why


    freopen("symbols.txt" , "r" , stdin);
    

    This is very bad! You're using std::freopen to associate a file with stdin. Then later on, you're using std::cin to read from the file. What you're doing is very "hacky" and this might work sometimes but not always. stdin (from C) and std::cin (from C++) are not required to be linked like this. freopen is a C API so you shouldn't use it in C++ anyway.

    What you should do is open an input file stream (std::ifstream) and read from that. That might look a little bit like this:

    #include <string> // std::string
    #include <fstream> // std::ifstream std::ofstream
    #include <iostream> // std::cerr
    
    int main() {
      std::ifstream symbols("symbols.txt");
      if (!symbols.is_open()) {
        // There was a problem opening the symbols file
        // Maybe it was missing
        // You should end the program here and write an error message
        std::cerr << "Failed to open \"symbols.txt\"\n";
        // returning an error code of 0 means "everything is fine"
        // returning anything else means "something went wrong"
        return 1;
      }
    
      // Try to choose more descriptive names than "X" and "Y"
      char X;
      std::string Y;
      while (symbols >> X >> Y && X != '#') {
        // ...
      }
    
      // ...
    }
    

    You code will be clearer if you create a new std::ifstream for each file you open (rather than reusing the same one). Error checking is important. You should make sure to check that the file actually opened before using it. To write your output to "handout.txt", you would use an output file stream (std::ofstream) instead.


    There's something that might trip you up. Take this "symbols.txt" file:

    A many words
    B on the same line
    C could cause problems
    #
    

    If we try to read it using the current code, we run into trouble:

    symbols >> X >> Y;
    // X is 'A'
    // Y is "many" rather than "many words" as you might expect
    

    If there's only one word on each line then this shouldn't be an issue, but if there are multiple words, then you might need to use std::getline. std::getline does what it says on the tin. It reads the whole line and writes it to the given string.

    You'd use it like this:

    while (symbols >> X && X != '#' && std::getline(symbols, Y)) {
      // ...
    }
    

    Please make sure you understand the code (read some of the links) before you copy it off of StackOverflow.