Thread: I/O with strings

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    30

    I/O with strings

    The object of my program is to read one line from a file, read a line from another file, compare the two and if file 1 is smaller than file 2, then it is supposed to write from file 1 to the output line and read a new line from file 1. Otherwise, it writes the line from file 2 to the output file and reads a new line from file 2. The program is supposed to do this while the end of neither file 1 of file 2 has been reached. Then if there is any line in file 1 or file 2 that still has not been written to the output file, the program should write those lines. Here is my code:
    Code:
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <cstdlib>     
    #include <fstream>  
    #include <cstring>  
    #include <string>
    
    using namespace std;
    
    int openFile(fstream& f, fstream& f1, fstream& f2);//function to open the files
    void readWriteData(fstream& f, fstream& f1, fstream& f2);//function to read and write data
    
    
    int main()
    {
        fstream outFile; //output
        fstream inFile1;//input
        fstream inFile2;//input
        
        openFile(outFile, inFile1, inFile2);
        cin.get();
        return 0;    
    }
    
    
    int openFile(fstream& outFile, fstream& inFile1, fstream& inFile2)
    {
        char outName[50];//storage of user input filename for the data file that is to be written to
        char inName1[50];//storage of user input filename for the first data file that is to be read from
        char inName2[50];//storage of user input filename for the second data file that is to be read from
        
        cout << "Please type the name of the first input file, including the extension: ";//requests user input of filename
        cin >> inName1;
        cout <<'\n';
        inFile1.open(inName1, ios::in);   
        if (inFile1.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << inName1 << "!" << endl;
                return EXIT_FAILURE;
            }
        
        cout << "Please type the name of the second input file, including the extension: ";//requests user input of filename
        cin >> inName2;
        cout <<'\n';
        inFile2.open(inName2, ios::in);
        if (inFile2.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << inName2 << "!" << endl;
                return EXIT_FAILURE;
            }    
            
        cout << "Please type the name of the output file, including the extension: ";//requests user input of filename
        cin >> outName;
        cout <<'\n';
        outFile.open(outName, ios::out);
        if (outFile.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << outName << "!" << endl;
                return EXIT_FAILURE;
            }
       
        readWriteData(outFile, inFile1, inFile2);
        return 0;
        
    }
    void readWriteData(fstream& outFile, fstream& inFile1, fstream& inFile2)
    {
         string in1;
         string in2;
      
    	 do
          {
    		  getline(inFile1, in1);
    		  getline(inFile2, in2);
               
                 if (strcmp(in1.c_str(), in2.c_str()) < 0)
                 {
                    outFile << in1 << '\n';
    				outFile << in2 << '\n';  
    			 }
                  
                else if (strcmp(in1.c_str(), in2.c_str()) > 0)
    			  {	
    	             outFile << in2 << '\n';
                     outFile << in1 << '\n';  
    			  }
    			else if (strcmp(in1.c_str(), in2.c_str()) == 0)
    			{
                    outFile << in1 << '\n';
    				outFile << in2 << '\n';  
    			 }
    		}
    	  while (!inFile2.eof() || !inFile1.eof());
    	  
    	   inFile1.close();
           inFile2.close();
           outFile.close();
    }
    When I use this code, there are duplicate lines put to the output file. If I use this code:
    Code:
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <cstdlib>     
    #include <fstream>  
    #include <cstring>  
    #include <string>
    
    using namespace std;
    
    int openFile(fstream& f, fstream& f1, fstream& f2);//function to open the files
    void readWriteData(fstream& f, fstream& f1, fstream& f2);//function to read and write data
    
    
    int main()
    {
        fstream outFile; //output
        fstream inFile1;//input
        fstream inFile2;//input
        
        openFile(outFile, inFile1, inFile2);
        cin.get();
        return 0;    
    }
    
    
    int openFile(fstream& outFile, fstream& inFile1, fstream& inFile2)
    {
        char outName[50];//storage of user input filename for the data file that is to be written to
        char inName1[50];//storage of user input filename for the first data file that is to be read from
        char inName2[50];//storage of user input filename for the second data file that is to be read from
        
        cout << "Please type the name of the first input file, including the extension: ";//requests user input of filename
        cin >> inName1;
        cout <<'\n';
        inFile1.open(inName1, ios::in);   
        if (inFile1.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << inName1 << "!" << endl;
                return EXIT_FAILURE;
            }
        
        cout << "Please type the name of the second input file, including the extension: ";//requests user input of filename
        cin >> inName2;
        cout <<'\n';
        inFile2.open(inName2, ios::in);
        if (inFile2.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << inName2 << "!" << endl;
                return EXIT_FAILURE;
            }    
            
        cout << "Please type the name of the output file, including the extension: ";//requests user input of filename
        cin >> outName;
        cout <<'\n';
        outFile.open(outName, ios::out);
        if (outFile.fail())//if file cannot be opened, a message will display
            {
                cerr << "Could not open " << outName << "!" << endl;
                return EXIT_FAILURE;
            }
       
        readWriteData(outFile, inFile1, inFile2);
        return 0;
        
    }
    void readWriteData(fstream& outFile, fstream& inFile1, fstream& inFile2)
    {
         string in1;
         string in2;
      
    	 do
          {
    		  getline(inFile1, in1);
    		  getline(inFile2, in2);
               
                 if (strcmp(in1.c_str(), in2.c_str()) < 0)
                 {
                    outFile << in1 << '\n';
    				outFile << in2 << '\n';  
    			 }
                  
                else if (strcmp(in1.c_str(), in2.c_str()) > 0)
    			  {	
    	             outFile << in2 << '\n';
                     outFile << in1 << '\n';  
    			  }
    			else if (strcmp(in1.c_str(), in2.c_str()) == 0)
    			{
                    outFile << in1 << '\n';
    				outFile << in2 << '\n';  
    			 }
    		}
    	  while (!inFile2.eof() && !inFile1.eof());
    	   
    
    	  do
    	  {
    		  if (inFile1.eof())
    			{
    				getline(inFile2, in2);
    				outFile << in2 << '\n';
    			}
    		  else if (inFile2.eof())
    		  {
    				getline(inFile1, in1);
    				outFile << in1 << '\n';
    
    		  }
    		}
    	  while (!inFile2.eof() || !inFile1.eof());
    	   inFile1.close();
           inFile2.close();
           outFile.close();
    }
    There are no duplicates but then the remainder of the output is not alphabetical. Does anyone know of a better way I can achieve what I want to do?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    C++ strings can be compared directly - and your comparisons are a bit overcomplicated - so simplified I'd do like this:
    Code:
    // Since equal strings can be in "either order" and still be correct, we just let the first case handle that.
                 if (in1 <= in2)
                 {
                    outFile << in1 << '\n';
    	        outFile << in2 << '\n';  
    	    }
                else 
                {	
                      outFile << in2 << '\n';
                      outFile << in1 << '\n';  
                }
    There is no need to get the C-string from a C++ string to compare the strings.

    If you still insist on using c_str() to get the string, why not do:
    Code:
    // Since equal strings doesn't matter, just cover this case here, rather than 
    // a separate case. 
    
              if (strcmp(in1.c_str(), in2.c_str()) <= 0)
              {
                   outFile << in1 << '\n';
      	       outFile << in2 << '\n';  
              }
    // As the only other alternative, we swap the strings. No need to compare the strings - they haven't changed.
              else 
              {	
    	        outFile << in2 << '\n';
                    outFile << in1 << '\n';  
    	  }
    This way, at least you are not comparing the same string up to 3 times (the compiler MAY realize that the strcmp() function always returns the same thing for the same input, but that's far from guaranteed).

    I prefer the first code-sequence.

    --
    Mats
    Last edited by matsp; 09-13-2007 at 02:18 AM. Reason: Fix broken tag.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question: Stream I/O (working with strings)
    By ckuttruff in forum C Programming
    Replies: 15
    Last Post: 05-19-2008, 11:32 AM
  2. Strings and File I/O
    By Yawgmoth in forum C++ Programming
    Replies: 2
    Last Post: 06-26-2003, 04:43 AM
  3. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM
  4. File I/O and Strings
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 05-25-2002, 10:02 PM
  5. strings and file i/o
    By batgirl in forum C++ Programming
    Replies: 2
    Last Post: 09-24-2001, 02:20 AM