0

I'm working on the following problem: I need to write a prgoram that reads an ASCII text file from the hard drive and allows the user to display and edit the contents of the file line-by-line. It must have the following features: It reads the file name from the standard output and opens the text file using a file stream. When the file is loaded, the user enters the text line number. If the line exists, it is displayed in the standard output. If the line does not exist (the user has entered a line number that is greater than the number of lines in the file), an error message is displayed, for example: The line 82 does not exist. When the line is displayed the user is given an option to enter a new string in the standard input that will become the contents of the line. The string can contain blank spaces. Then the user is asked to enter another line number.

Finally, the user is asked whether he wants to save the changes in the file or not. Technical requirements: The program must be composed by more than one function

This is my code so far:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

void printErrorMessage(int lineNumber)
{
    cout << endl << "  ERROR: The line " << lineNumber << " does not exist"
            << endl;
}

int main()
{

    int line_number;
    vector<string> TextVector;
    int loop = 1;
    fstream myfile;

    myfile.open("test.txt", std::fstream::in | std::fstream::out);
    while(loop == 1)
    {

        if (myfile.is_open())
        {
            // get end line of file.
            cout << "File has opened successfully." << endl;

        }
        else
        {
            cout << "File hasn't opened successfully.";
            return 0;

        }
        cout << "Enter the text line number:" << endl;
        cin >> line_number;

        size_t lines_count = 0;
        string line;

        while(getline(myfile, line))
        {
            TextVector.push_back(line); // push to text file
        }

        if(line_number > TextVector.size() + 1)
        {

            printErrorMessage(line_number);

            return 0;
        }

        cout << TextVector[line_number] << endl;

        cout << "If you'd like to change the line, please enter it, otherwise enter n to exit" << endl;
        string changeLine;
        getline(cin, changeLine);
        if (changeLine == "n")
        {
            myfile.close();
            return 0;
        }

        TextVector[line_number] = changeLine; // changes the line with the new string

        cout << "Would you like to enter a new line to edit? (Y/n)" << endl;
        string newLine;
        cin >> newLine;
        if (newLine != "y" && newLine != "Y")
        {

            cout << "Would you like to save all your changes to the file? (Y/n)" << endl;
            string saveChanges;
            cin >> saveChanges;
            if (saveChanges != "y" && saveChanges != "Y")
            {
                myfile.close();
                return 0;
            }

            for (int i = 0; i < TextVector.size() + 1; i++)
            {
                cout << TextVector[i] << endl;
                myfile << TextVector[i] << endl;
                myfile.flush();

            }

            myfile.close();
            return 0;
        }

    }
    return 0;

}

Technically I do save the changes to the vector, but for some reason I cannot get to overwrite the vector into the text file that already is full. Also, any idea why the getline(cin, changeLine); Still acts as if it's a normal string? shouldn't it get the whole line entered togethe with the spaces? Some guidance would really be appreciated!

user4581301
  • 29,019
  • 5
  • 26
  • 45
Arcana
  • 33
  • 4
  • Sorry! I wrote in a hurry. Thank for pointing it out. Is it alright now? – Arcana Jan 30 '18 at 23:39
  • Recommendations: 1. "The program must be composed by more than one function" Embrace this instruction. Chop `main` up into more functions. `readfile`, `writefile`, and `editline` sounds about right. Then test each function individually. This should help you narrow down the location of errors. 2. When writing the file don't forget to `seekp` to the beginning of the file. You may find it easier (but probably slower) to open the file, write the `vector` to the file, and close the file again. – user4581301 Jan 31 '18 at 00:19
  • Thanks for the advice so far! Any idea why the console doesn't stop at getline(cin, changeLine) ? Isn't it supposed to wait for my input? – Arcana Jan 31 '18 at 01:00
  • `cin >> line_number;` doesn't eat the end of line that's placed in the stream when you hit enter. More details and solutions here: https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction Didn't get from your question that that was what your problem was. – user4581301 Jan 31 '18 at 01:04
  • Possible duplicate of [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – user4581301 Jan 31 '18 at 01:06
  • User, that's one of the issues, really. My main one is not being able to get the vector to get written over the lines in the text file. I'm not sure if I've mentioned, but the text file already has text in it. So I'm not sure if I can overwrite, firstly. Secondly, the issue is even though the vector has the correct sequence of strings, it still doesn't copy in. – Arcana Jan 31 '18 at 01:16
  • [There are a whole bunch of ways you can open a file to write.](http://en.cppreference.com/w/cpp/io/basic_fstream/open) Since you are rewriting the entire contents every time, open the file for reading (default behaviour of `std::ifstream`), read in, close the file. Later when you want to write, open the file for writing (`std::ofstream`), write the file, and close the file. – user4581301 Jan 31 '18 at 01:39
  • Okay to give a little update. I managed to fix the issue with the writing to the file. It seems that I had to close the file first after reading from it, to flush out the stream(I think that's what the term was) and then open it up again to write to. My remaining issue right now is to make a readfile, writefile function. – Arcana Feb 01 '18 at 18:10
  • I tried the following `void writeVector(vector vektor, string lines, ofstream myfile1){ for (int i = 0; i < vektor.size() + 1; i++){ cout << vektor[i] << endl; myfile1 << vektor[i] << endl; } myfile1.close(); }` However I get ios_base error? Any ideas? – Arcana Feb 01 '18 at 18:11

0 Answers0