Output contents of user designated file to new file

Hi, all,

I am attempting to write the code to read the contents of a text file (composed of a multi-line header and a long list of nine character words). The program will allow the user to select the input file. The program will read the contents of the file and output them to a new text file. I am using CodeBlocks 12.11 on a Windows XP Pro system. The code I have written is just 40 lines. It builds and runs fine and appears to output perfectly to the console, but sadly will not populate the file it creates with any data at all. As a beginner, I have tried unsuccessfully for hours to figure out how to make this work by reading tutorials, by studying sample code, by researching related topics on this forum, and by rearranging and changing the code in dozens of ways. I would be very grateful for some help. Here is my code. Everything seems to runs fine until the few lines of code after the contents of the input file are output to console, beginning with ofstream mynewfile ("Outputfile.txt");.

Thanks, MHL

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
string line;
ifstream myfile;
ofstream mynewfile;

cout << "Please enter the input file name and location> " << flush;
while (true)
{
myfile.close();
myfile.clear();
string myfilename;
getline( cin, myfilename );
myfile.open( myfilename.c_str() );
if (myfile) break;
cout << "Invalid file. Please enter a valid input file name and location> " << flush;
}

if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;

ofstream mynewfile ("Outputfile.txt");
if (mynewfile.is_open())
{
mynewfile << line << endl;
}
}

myfile.close();
}

else cout << "Unable to open file";
return 0;
}
Please use code tags when posting code:
http://cplusplus.com/articles/jEywvCM9/

1
2
3
4
5
6
7
8
9
10
11
cout << "Please enter the input file name and location> " << flush;
while (true)
{
myfile.close();
myfile.clear();
string myfilename;
getline( cin, myfilename );
myfile.open( myfilename.c_str() );
if (myfile) break;
cout << "Invalid file. Please enter a valid input file name and location> " << flush;
}


Heh that's a bit unorthodox... interesting approach though.

1
2
3
4
5
6
ofstream mynewfile ("Outputfile.txt");
if (mynewfile.is_open())
{
mynewfile << line << endl;
}
}


From what I can see you open the same file over and over in the while() loop.

Move ofstream mynewfile ("Outputfile.txt"); just before: if (myfile.is_open())

Last edited on
In your while loop yo do this:
ofstream mynewfile ("Outputfile.txt");
This will open Outfile.txt for writing on each iteration, removing all previous content. So only last writing will stay. And it probably will be empty string.
TO solve this, open your file before the loop.
Hi, Catfish3,
Hi, MiiNiPaa,

Thank you both for solving my dilemma.
Also, thank you for teaching me to use code tags.
Your suggestions fixed my problem.
Of course, as a noob, I have many more problems with my code.
After I fixed my code, as you suggested, I tried to insert the relevant portions into my project. The code worked, but I must have put it in the wrong place, because it caused my other code not to work!

The attached code (without the indented code in the middle - see lines 45 to 58 in the code tagged code below) works to read a user-entered text file and then output values from a map to a new text file. However, I need to make a copy of the user input file first, because I want to modify its contents, and I don't want to risk damaging the original file. (I want to remove the first five characters from each line of nine characters in the input file before testing them against the map. I also have to deal with a header in the input file, but that is too much for me right now.)

When I added the code to copy the file (indented in middle of code attached below), it copied the file to a new file as intended, but then the map routine, which worked fine without the new code, returned the error "Sorry '' Not in move list." How can I fix the code so that both parts work to (1) copy the input file to a new file, and (2) return the map values to the output file?

Here is the output from the console window.


PMAABQQQQ PMABWEHHE PMACBEEEE
Please enter the input file name and location> Testing.TXT
PMAABQQQQ
PMABWEHHE
PMACBEEEE
Sorry, `' not in move_list.
Process returned 0 (0x0)   execution time : 9.391 s
Press any key to continue.


Thanks for your help, MHL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <map>
#include <string>
#include <fstream>
using namespace std;
int main()

{
        std::map<std::string, std::string> move_list;

move_list["XXXXXXXXX"] = "ABCD";
move_list["YYYYYYYYY"] = "EFGH";
move_list["ZZZZZZZZZ"] = "IJKL";

        for (std::map<std::string, std::string>::const_iterator ci = move_list.begin();
                ci != move_list.end();
                ci++

                )
                std::cout << (*ci).first << ' ';

    std::cout << std::endl;

        std::string TXT;

        //ask user for file name
    ifstream myfile;
    string line;
    ofstream copyfile ("Outputfile.txt");

  cout << "Please enter the input file name and location> " << flush;
  while (true)
    {
    myfile.close();
    myfile.clear();
    string myfilename;
    getline( cin, myfilename );
    myfile.open( myfilename.c_str() );
    if (myfile) break;
    cout << "Invalid file. Please enter a valid input file name and location> " << flush;
    }

  if (myfile.is_open())
                          //New code to copy input file to new file
                          {
                            while ( myfile.good() )
                            {
                              getline (myfile,line);
                              cout << line << endl;

                                    {
                             copyfile << line << endl;
                            }
                                      }

                             }

                          else cout << "Unable to open file";

                          //end of new code to copy input file
    {
      while(getline (myfile,TXT))

      {

        std::ofstream mynewfile ("Testing.TXT", ios::app);
  if (mynewfile.is_open())
  {
    mynewfile << (*move_list.find(TXT)).second <<std::endl;
    mynewfile.close();
  }
  else std::cout << "Unable to open file";

      }

   myfile.close();
      }

  else std::cout << "Unable to open file";

        if (move_list.count(TXT) == 0)
                std::cout << "Sorry, `" << TXT << "' not in move_list.";
        else

         std::cout << std::endl;

}
I didn't look into your problem yet, but if your compiler is C++11 conformant, you can make iteration over container easy:
0.5) There is -> operator (pointer member selection):
std::cout << ci->first << ' ';

1) there is an auto keyword:
for(auto ci = move_list.cbegin(); ci != move_list.cend(); ++ci)//cbegin()/cend() returns const_iterator

2) Better yet, there is range-based for loop:
1
2
for(const auto& ci: move_list)//ci will be a const reference to map data
    std::cout << ci.first << ' ';



EDIT: There is a dangling else which doest correspond to any if. Looks like you mess with parentheses. Fix it so we can compile your code and fing the error bothering you.
Last edited on
Hi, MiiniPaa,

I removed the dangling else at line 79.
I don't know what parentheses to fix. My apologies.
The code you show at 1 and 2 would not compile for me.
The code at .5 compiles but gives the same error as the existing code.
I don't know if my compiler is C++11 conformant.
If I have not followed your instructions properly, I apologize again.
If you could tell me again what I need to do in a different way, I will try to do it.

Thanks,
MHL
Please format your code with a little discipline.
You had a dangling else at line 79, I removed it.

Also, C++11 is the 2011 standard of C++. Visual C++ 2008 and 2010 have poor support for it. Visual C++ 2012 doesn't fully support either.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <map>
#include <string>
#include <fstream>
using namespace std;
int main()

{
    std::map<std::string, std::string> move_list;

    move_list["XXXXXXXXX"] = "ABCD";
    move_list["YYYYYYYYY"] = "EFGH";
    move_list["ZZZZZZZZZ"] = "IJKL";

    for (std::map<std::string, std::string>::const_iterator ci = move_list.begin();
            ci != move_list.end();
            ci++

        )
        std::cout << (*ci).first << ' ';

    std::cout << std::endl;

    std::string TXT;

    //ask user for file name
    ifstream myfile;
    string line;
    ofstream copyfile ("Outputfile.txt");

    cout << "Please enter the input file name and location> " << flush;
    while (true)
    {
        myfile.close();
        myfile.clear();
        string myfilename;
        getline( cin, myfilename );
        myfile.open( myfilename.c_str() );
        if (myfile) break;
        cout << "Invalid file. Please enter a valid input file name and location> " << flush;
    }

    if (myfile.is_open())
        //New code to copy input file to new file
    {
        while ( myfile.good() )
        {
            getline (myfile,line);
            cout << line << endl;

            {
                copyfile << line << endl;
            }
        }

    }

    else cout << "Unable to open file";

    //end of new code to copy input file
    {
        while(getline (myfile,TXT))

        {

            std::ofstream mynewfile ("Testing.TXT", ios::app);
            if (mynewfile.is_open())
            {
                mynewfile << (*move_list.find(TXT)).second <<std::endl;
                mynewfile.close();
            }
            else std::cout << "Unable to open file";

        }

        myfile.close();
    }

    if (move_list.count(TXT) == 0)
        std::cout << "Sorry, `" << TXT << "' not in move_list.";
    else

        std::cout << std::endl;

}
Lines 43-56 you are copying content to new file. After that routine failbit and eof bit will be set and next input operation will try to read past end of file. then at line 62 you are trying to read again.
Thank you MiiNiPaa!
I know it is difficult to have patience for a beginner.
Following your advice, I was able to fix the code so now it copies the input file and writes the map values to a new file!

Next, my challenge will be to change the headers in the input file copy and write reconfigured headers to the output file, then remove the first five characters from each nine character word in the input file copy so I can populate the map with less than 400 words instead of more than 129,000 words.

The input file will look something like this...

Stuff line 1
Stuff line 2
Stuff line
...
etc for a few more lines

ABCDEFGHI
JKLMNOPQR
STUVWXYZA
...
and so on for up to 400 lines or more.
Hi, again,

Thanks to help from people in this forum, I have my file working, but it is clunky and inefficient. I am trying to clean up the code and learn more abut c++ programming at the same time. My task is as follows:

1. Get file from user (okay)
2. Create a new file using user's file name with new extension (okay, but inefficient)
3. Copy user's file to a new file (okay)
4. Perform operations on copy of file and send output to new file created in 2 (stuck)

Here is my code for items 1-4. I need help writing the code for item 4 to send text from the copy of user's file, which I will modify, to the new file. Presently, I am only able to figure out how to send it to a file I designate.

It would also be nice if I could erase all four last characters of the user file (the extension) in one line, rather than four lines (lines 24-27), but I am having trouble with that, too.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()

{

    string NGS;
    ifstream myfile;
    ofstream copyfile ("Copy.NGF");

  cout << "Please enter the input file name and location> " << flush;


  while (true)
    {
    myfile.close();
    myfile.clear();
    string filename;
    getline( cin, filename );
    myfile.open( filename.c_str() );
    filename.erase (filename.end()-1);
    filename.erase (filename.end()-1);
    filename.erase (filename.end()-1);
    filename.erase (filename.end()-1);
    filename += ".SGF";
    ofstream newfile (filename.c_str());

    if (myfile) break;
    cout << "Invalid file. Please enter a valid input file name and location> " << flush;

    }

  if (myfile.is_open())

    {
      while(getline (myfile,NGS))

      {
        copyfile << NGS << endl;

      }
      copyfile.close();
    }

  else cout << "File is not accessible." << endl;

     ifstream inputfile;
     inputfile.open("Copy.NGF");
     ofstream outputfile ("New2.SGF" , ios::app); //I don't want "New2.SGF" here.
     //I want the output to go to the new file created on line 29
     string line1;
     getline(inputfile,line1);
     outputfile << line1 << " modified." << endl;
    
}




Topic archived. No new replies allowed.