Copy, Translate, and Save Text File

Discussion in 'C++' started by Michael Lester, Apr 3, 2013.

  1. Question: How to copy user designated text file containing vocabulary list,translate its contents, and save the new file to the same directory as original file with a new file extension.

    Details: I am new to programming. I have a compiler (Code-Blocks 12.11). Asan exercise, I would like help to write a program that will allow a student to enter a text file location and file name, and the desired output language. The program will then translate the text in the file into one of a dozen or more languages using a csv vocabulary file with the vocabulary words in rows and the translations in columns and save the new file as a text file to the same directory with a new file extension. The program knows the source language from the file extension of the source file.

    Thanks,
    Michael

    Sample original text file [Vocab List - Animals.eng]

    English Vocabulary List
    Animals
    Mrs. Howard
    Language Lab
    Summer 2013

    Start
    alligator
    ant
    bear
    bee
    bird
    camel
    cat
    cheetah
    chicken
    chimpanzee
    cow
    crocodile
    deer
    ....
    End

    *****

    Sample output file [Vocab List - Animals.spa]

    Spanish Vocabulary List
    Animals
    Mrs. Howard
    Language Lab
    Summer 2013

    Start
    Alligator
    oso
    aves
    abeja
    camello
    cat
    pollo
    chimpancé
    chita
    vacacocodrilo
    ciervos
    ....
    End
    Michael Lester, Apr 3, 2013
    #1
    1. Advertising

  2. Michael Lester

    Stefan Ram Guest

    Michael Lester <> writes:
    >Question: How to copy user designated text file containing
    >vocabulary list, translate its contents, and save the new
    >file to the same directory as original file with a new file
    >extension.


    Someone who asks here how to save a text to a directory
    cannot be technically capable to program a proper
    translation of natural-language texts.

    (The meaning of a word usually depends on the context,
    the idea of a 1-to-1 mapping of words between natural
    languages is false. A proper translation usually even
    changes the number of words and the structure of phrases.

    I'd suggest to modify the assignment so as to do something
    that can be covered with the current capabilities of the
    students, such as determining word frequencies.)
    Stefan Ram, Apr 3, 2013
    #2
    1. Advertising

  3. Michael Lester

    Stefan Ram Guest

    -berlin.de (Stefan Ram) writes:
    >I'd suggest to modify the assignment so as to do something
    >that can be covered with the current capabilities of the
    >students, such as determining word frequencies.


    Or, otherwise, to change the description of the task
    from »translation« to »word replacements«, not claiming
    that simplistic 1-by-1 word replacements were a »translation«.
    Stefan Ram, Apr 3, 2013
    #3
  4. On Tuesday, April 2, 2013 9:01:42 PM UTC-7, Michael Lester wrote:
    > Question: How to copy user designated text file containing vocabulary list, translate its contents, and save the new file to the same directory as original file with a new file extension.


    Okay, I need to take smaller bites.

    I found some C source code that compiles in C++ and will copy a file to a new file with user input to locate the source file and declare the output file.

    I also found some code that is supposed to find and replace text, but it only reads the text, and I don't know what I am doing wrong.

    // print the content of a text file.
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;

    int main () {

    // This is where we'll put the stuff we read from file
    char buffer[ 100 ];


    // Fill the buffer with zeros (char strings must be null-terminated)
    fill_n( buffer, 100, '\0' );



    ifstream infile;

    infile.open ("Test3.txt", ifstream::in);

    while (infile.good())

    // Read as many as 100 bytes (chars) from the file and stick them in our array
    infile.read( buffer, 100 );

    // Convert that char array into a STL string, and show the user what we got.
    string g( buffer );


    string str2="exit";
    string str="t";


    g.replace(g.find(str2), str2.length(), "str");

    cout << buffer << " successfully read from file.\n";


    infile.close();

    return 0;
    }
    Michael Lester, Apr 3, 2013
    #4
  5. Michael Lester

    Stefan Ram Guest

    Michael Lester <> writes:
    >I don't know what I am doing wrong.


    If you do not know the meaning of a single word of the
    source file you have posted (supposedly after you had
    obtained permission from their authors to do this), we can
    answer. But if you do not know the meaning of many parts,
    it's better to read a good book or take a course with a good
    teacher.

    For a book, you might try »Programming -- Principles and
    Practice Using C++«.

    http://www.stroustrup.com/Programming/
    Stefan Ram, Apr 3, 2013
    #5
  6. Thank you very much for the help Paavo. I will spend some time working on implementing your suggestions and see if can work this out.

    Sincerely,
    Michael

    On Wednesday, April 3, 2013 8:59:52 AM UTC-7, Paavo Helde wrote:
    >
    > On Tuesday, April 2, 2013 9:01:42 PM UTC-7, Michael Lester wrote:
    > Question: How to copy user designated text file containing vocabulary
    > list, translate its contents, and save the new file to the same
    > directory as original file with a new file extension.
    >
    >
    > For starters, get rid of those C-style buffers and use std::getline
    > instead to read in full lines into a std::string


    > > g.replace(g.find(str2), str2.length(), "str");

    >
    > std::string find() searches for substrings inside strings. This is not
    > what you need, leaving aside that you have made several errors in a
    > single line here. For example, it would find and replace "horse" inside a
    > "seahorse".
    >
    > If your input is one word per line, then you can just compare strings, no
    > find() needed. If your input is multiple words per line, then you need to
    > split them up into words anyway, so again you can just compare words.


    > For the dictionary you will want to create and populate a std::map or
    > something like that for fast lookup of the words.


    >> infile.close();


    > this is not needed.
    Michael Lester, Apr 4, 2013
    #6
  7. On Wednesday, April 3, 2013 8:59:52 AM UTC-7, Paavo Helde wrote:

    > For the dictionary you will want to create and populate a std::map or
    > something like that for fast lookup of the words.


    > > On Tuesday, April 2, 2013 9:01:42 PM UTC-7, Michael Lester wrote:
    > >> Question: How to copy user designated text file containing vocabulary
    > >> list, translate its contents, and save the new file to the same
    > >> directory as original file with a new file extension.


    Sorry for the bad snip job...

    Paavo has helped me understand more about how to do what I want to do, and I am hoping for some additional guidance.

    I have code that will read the first line of my old file and write the sameline to my new file (Code 1). I also have separate code that will read user input and replace the input using a std::map database (Code 2). I would like to know how to integrate Code 1 and Code 2 into one project so that (a)the std:map (Code 2) will use the line read by Code 1 from the old file tofind the replacement text in the database instead of asking for user input, then (b) Code 1 will write the new text to the new file, and (c) the codewill repeat to the end of the file with a loop, or something.

    Here are the two codes I have:

    Code 1

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

    int main () {
    string line;
    ifstream myfile ("Test.old");
    if (myfile.is_open())
    {

    {
    getline (myfile,line);
    cout << line << endl;
    }
    myfile.close();
    }

    else cout << "Unable to open file";


    ofstream mynewfile ("Test.new");
    if (mynewfile.is_open())
    {
    mynewfile << line;

    mynewfile.close();
    }
    else cout << "Unable to open file";

    return 0;
    }

    Code 2

    #include <iostream>
    #include <map>
    #include <string>

    int main()
    {
    std::map<std::string, std::string> database;

    database["ABCDEFGHI"] = "1234";
    database["BCDEFGHIJ"] = "2345";
    database["CDEFGHIJK"] = "3456";
    std::cout << "What word do want to find?\nAvailable: ";

    for (std::map<std::string, std::string>::const_iterator ci = database.begin();
    ci != database.end();
    ++ci
    )
    std::cout << (*ci).first << ' ';

    std::cout << std::endl;

    std::string name;

    std::getline(std::cin, name);

    if (database.count(name) == 0)
    std::cout << "Sorry, `" << name << "' not in database.";
    else
    std::cout << name << ": " << (*database.find(name)).second;

    std::cout << std::endl;
    }
    Michael Lester, Apr 4, 2013
    #7
  8. On Thursday, April 4, 2013 9:02:04 AM UTC-7, Paavo Helde wrote:
    > Michael Lester wrote >> >
    >
    > > I have code that will read the first line of my old file and write the
    > > same line to my new file (Code 1). I also have separate code that will
    > > read user input and replace the input using a std::map database (Code
    > > 2). I would like to know how to integrate Code 1 and Code 2 into one
    > > project so that (a) the std:map (Code 2) will use the line read by
    > > Code 1 from the old file to find the replacement text in the database
    > > instead of asking for user input, then (b) Code 1 will write the new
    > > text to the new file, and (c) the code will repeat to the end of the
    > > file with a loop, or something.

    >
    >
    > Seems you already have all the pieces, you should just merge them together.
    > The final program should be something like:
    >


    > populate map
    > open old and new files
    > while(getline(...)) {
    > process line and write to the new file


    > }
    > done


    > hth
    > Paavo


    Hi, Paavo,

    I am almost there, I think! Thank you for your help to get me this far.

    The following code appears to read all lines from my input file, but only outputs the last line to my output file. I want to populate the output file with all the values for which there are keys in the input file, not just the last value.

    Will you help me a little more, please?

    Thanks,
    Michael

    #include <iostream>
    #include <map>
    #include <string>
    #include <fstream>
    using namespace std;
    int main()
    {
    std::map<std::string, std::string> move_list;

    move_list["AAAAAAAAA"] = "aaaa";
    move_list["BBBBBBBBB"] = "bbbb";
    move_list["CCCCCCCCC"] = "cccc";

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

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

    std::cout << std::endl;

    std::string XYZ;


    std::ifstream myfile ("Test.XYZ");
    if (myfile.is_open())
    {

    {
    while (getline (myfile,XYZ));
    std::cout << XYZ << std::endl;
    }
    myfile.close();
    }

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



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

    std::eek:fstream mynewfile ("Test.ABC", ios::app);
    if (mynewfile.is_open())
    {
    mynewfile << (*long_word.find(XYZ)).second;

    mynewfile.close();
    }
    else std::cout << "Unable to open file";

    std::cout << std::endl;

    }
    }
    Michael Lester, Apr 5, 2013
    #8
  9. On Thursday, April 4, 2013 9:02:04 AM UTC-7, Paavo Helde wrote:
    > Michael Lester wrote >> >
    >
    > > I have code that will read the first line of my old file and write the
    > > same line to my new file (Code 1). I also have separate code that will
    > > read user input and replace the input using a std::map database (Code
    > > 2). I would like to know how to integrate Code 1 and Code 2 into one
    > > project so that (a) the std:map (Code 2) will use the line read by
    > > Code 1 from the old file to find the replacement text in the database
    > > instead of asking for user input, then (b) Code 1 will write the new
    > > text to the new file, and (c) the code will repeat to the end of the
    > > file with a loop, or something.

    >
    >
    > Seems you already have all the pieces, you should just merge them together.
    > The final program should be something like:
    >


    > populate map
    > open old and new files
    > while(getline(...)) {
    > process line and write to the new file


    > }
    > done


    > hth
    > Paavo


    Hi, Paavo,

    I am almost there, I think! Thank you for your help to get me this far.

    The following code appears to read all lines from my input file, but only outputs the last line to my output file. I want to populate the output file with all the values for which there are keys in the input file, not just the last value.

    Will you help me a little more, please?

    Thanks,
    Michael

    #include <iostream>
    #include <map>
    #include <string>
    #include <fstream>
    using namespace std;
    int main()
    {
    std::map<std::string, std::string> move_list;

    long_word["AAAAAAAAA"] = "aaaa";
    long_word["BBBBBBBBB"] = "bbbb";
    long_word["CCCCCCCCC"] = "cccc";

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

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

    std::cout << std::endl;

    std::string XYZ;


    std::ifstream myfile ("Test.XYZ");
    if (myfile.is_open())
    {

    {
    while (getline (myfile,XYZ));
    std::cout << XYZ << std::endl;
    }
    myfile.close();
    }

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



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

    std::eek:fstream mynewfile ("Test.ABC", ios::app);
    if (mynewfile.is_open())
    {
    mynewfile << (*long_word.find(XYZ)).second;

    mynewfile.close();
    }
    else std::cout << "Unable to open file";

    std::cout << std::endl;

    }
    }
    Michael Lester, Apr 5, 2013
    #9
  10. Michael Lester

    ?? Tiib Guest

    On Friday, 5 April 2013 10:34:35 UTC+3, Michael Lester wrote:
    >
    > The following code appears to read all lines from my input file,
    > but only outputs the last line to my output file.


    That is exactly what your program does:

    > [...]
    > while (getline (myfile,XYZ));
    > std::cout << XYZ << std::endl;
    > [...]


    Putting ';' after while is dangerous because it is often hard to
    notice and reader (even yourself few months later) may misunderstand
    your original intentions. Use syntax like:

    while (getline (myfile,XYZ))
    { }

    As I understand you just want to remove that semicolon to output
    all lines read not only last line.
    ?? Tiib, Apr 5, 2013
    #10
  11. On Friday, April 5, 2013 1:55:03 AM UTC-7, ?? Tiib wrote:
    > On Friday, 5 April 2013 10:34:35 UTC+3, Michael Lester wrote:
    >
    > >

    >
    > > The following code appears to read all lines from my input file,
    > > but only outputs the last line to my output file.

    >
    > That is exactly what your program does:


    > > [...]
    > > while (getline (myfile,XYZ));
    > > std::cout << XYZ << std::endl;
    > > [...]

    >
    > Putting ';' after while is dangerous because it is often hard to
    > notice and reader (even yourself few months later) may misunderstand
    > your original intentions. Use syntax like:
    >
    > while (getline (myfile,XYZ))
    > { }
    >
    > As I understand you just want to remove that semicolon to output
    > all lines read not only last line.


    Thank you, ?? Tiib!
    Thanks to Paavo, and the others who helped me, too.

    With this last change (and moving my "output to file" routine up to replace
    std::cout << XYZ << std::endl;
    the program now seems to work as intended.

    I will have to deal with replacing the headers in the input file now to getthe new headers into the new file, but I will spend some time fooling around with that myself to see what I can figure out.
    Michael Lester, Apr 5, 2013
    #11
  12. On Friday, April 5, 2013 9:14:57 AM UTC-7, Michael Lester wrote:

    > the program now seems to work as intended.
    >
    > I will have to deal with replacing the headers in the input file now to get the new headers into the new file, but I will spend some time fooling around with that myself to see what I can figure out.


    I have tried for the past five hours to figure out how to output the user selected input text file to a new text file. I will use the copy to manipulate the data (a multi-line header and a long list of nine character words). I will need to remove the first five characters of each word, but that willbe my next challenge.

    I have written a test program which outputs the entire contents of the input file to the console as intended, and creates the new file, but does not put any data in the new file. I have pasted 40 lines of code below. If I getit working, I will attempt to integrate it into the code I posted here previously.

    I would very much appreciate any help you are willing to give.

    Sincerely, Michael

    #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;
    }
    Michael Lester, Apr 6, 2013
    #12
  13. Michael Lester

    Ike Naar Guest

    On 2013-04-06, Michael Lester <> wrote:
    > #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();


    In the first iteration of the while loop, myfile is not associated
    with an open file. Closing it is an error.

    > 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");


    Why is mynewfile re-opened for every line in myfile?

    > if (mynewfile.is_open())
    > {
    > mynewfile << line << endl;
    > }
    > }
    >
    > myfile.close();
    > }
    >
    > else cout << "Unable to open file";
    > return 0;
    > }
    Ike Naar, Apr 6, 2013
    #13
  14. Thank you for your help Ike, and the others who have helped me make progress on this.

    The attached code (without the indented code in the middle - see below) works to read a user-entered text file and then output values from the 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 damagingthe 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 attachedbelow), 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?

    Thanks for your help.

    #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;

    //New code to 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::eek:fstream 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;

    }
    Michael Lester, Apr 6, 2013
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Smith
    Replies:
    0
    Views:
    537
    Alex Smith
    Jun 15, 2005
  2. Alex
    Replies:
    2
    Views:
    1,199
  3. Replies:
    26
    Views:
    2,083
    Roland Pibinger
    Sep 1, 2006
  4. Shahar Golan
    Replies:
    5
    Views:
    278
    kaeli
    Oct 16, 2003
  5. MaggotChild

    File::Copy::copy With File Handles

    MaggotChild, Oct 18, 2011, in forum: Perl Misc
    Replies:
    2
    Views:
    490
    Ilya Zakharevich
    Oct 22, 2011
Loading...

Share This Page