0

I believe my error is within my writeline function, when I attempt to write the contents of the vector to the new file using a while loop.

//Read from txt file, write to new text file

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

void readline();
void sortline(vector<string>& sortthis);
void writeline(vector<string>& list);

int main()
{
    readline();
    system("pause");
    return 0;
};

void readline()
{
    string line;
    vector<string> lines;
    ifstream myfile("classes.txt");
    if (myfile.is_open())
    {
        while (myfile.good())
        {
            getline(myfile, line);
            lines.push_back(line);
        };
        myfile.close();
    }
    cout << "readline() has run" << endl;
    sortline(lines);
    writeline(lines);
};

void  sortline(vector<string>& sortthis)
{
    sort(sortthis.begin(), sortthis.end());
};

void  writeline(vector<string>& list)
{
    ofstream myfile2("new.txt");
    if (myfile2.is_open())
    {
        int i = 0;
        while(i !=list.size()-1)
        {
            myfile2 << list[i] << endl;
            i++;
        };
        myfile2.close();
    };
     cout << "writeline() has run" << endl;
};

this is a project from a semester ago that i'm revisiting. I wrote the program on my mac, now i'm trying to run it on my windows comp with visual studio. I'll describe what I'm attempting to do, I apologize if my choice of words is terrible in advance. anywhere I put a * is where I'm not sure what is happening, but I'll take a stab at it.. any explanations of my code is very appreciated!!

my readline() function does the following: creates a string called line, creates a vector of string type called lines, **input the file classes.txt and establish myfile as it's object, then open myfile for writing, **use the while loop to write the lines from the txt into the myfile object, then close myfile, print out a statement to let the user know readline() has run, then **pass the vector called lines into the sortline function, and then pass lines into the writeline function.

** sortline takes in a vector of strings as its arg, and assigns it the object sortthis?? then I'm not sure what happens, but it looks like i applied a sorting algorithm, anybody have any thoughts?

and finally we get to my writeline function which takes in a vector of strings as its arg and assigns them the name lines (is that correct?) i then want to establish a new out file stream to a new textfile called "new.txt" with an object name myfile2, if myfile2 is open, then i want to write all the lines from the vector of strings(which contain the contents of the original text file) into myfile2, which will write them to the new.txt file, then close myfile2, print a message stating the function has run, and that is all.

mcdito13
  • 191
  • 1
  • 3
  • 13
  • 2
    Why do you end your function body brace with a semicolon? – Andreas DM Aug 02 '15 at 01:14
  • Give your input, output including exact error message, and expected output. Read [this](https://stackoverflow.com/help/mcve). – philipxy Aug 02 '15 at 01:15
  • 1
    Your `writeline` function has an argument with a very bad name: `list`. It's very bad because the word "list" could clash with [std::list](http://en.cppreference.com/w/cpp/container/list) and because it is not a list, it's a vector. And names should describe the content, not the container, so "lines" is a better name, keep it. That said, if your vector contains say 3 elements, when you call `list.size()` it will return 3. Therefore the loop exit condition should be `i !=list.size()`, not `i !=list.size()-1`. Other than that, you should give us more details as explained by philipxy. – Fabio says Reinstate Monica Aug 02 '15 at 01:31
  • Is it possible that you have an empty file ? – Christophe Aug 02 '15 at 01:33
  • 2
    What is your question? "I'm stuck" is not a question. – Lightness Races in Orbit Aug 02 '15 at 01:51
  • Andreas - getting back into c++ after a hiatus.. going to fix those bad habits asap. – mcdito13 Aug 02 '15 at 04:01
  • philipxy/fabio - this is my first post, i will work on posting more specific questions christophe - the classes.txt file is not empty – mcdito13 Aug 02 '15 at 04:31
  • @mcdito13: when you write a comment, the author of the question/answer you are commenting on is automatically notified. Plus, you can add ONE more user to notify, by putting a `@` before his name, as I have just done (but in this case it is not needed, because you are the author of the question). That said, we still don't know what your problem is. In the title you mention an error: both I and Tas told you what to do. Then you have edited your question, saying you don't understand what the code is doing. What is your question exactly? Can you copy the error given by the compiler exactly? – Fabio says Reinstate Monica Aug 02 '15 at 14:12
  • @FabioTurati I have now modified my code and it runs without any errors. Here is my new writeline function: void writeline(vector& lines) { ofstream myfile2("new.txt"); if (myfile2.is_open()) { for (int i = 0; i < lines.size(); ++i) myfile2 << lines[i] << endl; myfile2.close(); }; cout << "writeline() has run" << endl; } apologize for the bad format, will work on making it easier to read. The program runs, makes a "new.txt" file BUT, MY PROBLEM is that there is nothing in the file. Why would that be? – mcdito13 Aug 02 '15 at 19:00
  • @mcdito13 At this point you need a debugger (or even some `cout`s at the right places, depending on what is more convenient). Are you sure that `lines` is not empty? Try printing the size of `lines`. Then try to print the content of every line. If there are none, or they are empty, the problem is when you read the file. – Fabio says Reinstate Monica Aug 02 '15 at 19:26
  • @FabioTurati I placed a cout << lines[1] << endl; immediately after I close myfile2 and i received this: Debug Assertion Failed! Program: C\windows\system32\msvcp140D.dll File: c:\programfiles (x86)\microsoft visual studio 14.0\vc\include\vector Line: 1232.......Expression: vector subscript out of range – mcdito13 Aug 02 '15 at 19:58
  • @mcdito13 This means that the second element (remember, vectors are 0-based) doesn't exist. If you expect to find it, it means that something went wrong when you read the content of the file. Try to isolate the exact point where things start to differ from what you expect. – Fabio says Reinstate Monica Aug 02 '15 at 23:40

1 Answers1

0

The way you loop through list in writeline is not safe. You should use a for loop or a while loop with iterator. As it is, your code probably doesn't do what you intend it to do even if there are several elements in list. Consider the following:

std::vector<std::string> vLines;
vLines.push_back("Hello");
vLines.push_back("File");
vLines.push_back("World");
std::ofstream of("file.txt");
int i = 0;
while (i != vLines.size() - 1)
{
    of << vLines[i] << std::endl;
    ++i;
}

Even with several elements in vLines, this will only actually print output 2 elements into of.
i will be 0 which is not 2, so "Hello" will be output to of.
i will be 1 which is not 2, so "File" will be output to of.
i is now 2, which is equal to 2, so "World" will not be output to of.

That's with elements. If there are 0 elements in vLines, you will be indexing out of bounds (which I suspect is what you are doing, hence your error):

std::vector<std::string> vLines;
std::ofstream of("file.txt");
int i = 0;
while (i != vLines.size() - 1)
{
    of << vLines[i] << std::endl;
    ++i;
}

i will be 0, which is not equal to -1, so the code will run and try to output vLines[0] to of, but there is no vLines[0]! I suspect this is what you are experiencing.

This will go away if you use a proper range-based loop instead (credit to @WhozCraig for C++11 solution):

for (auto const& s : vLines)
    of << s;

Or if you don't have C++11 you can still mimic a proper range-based loop with the following:

for (int i = 0; i < vLines.size(); ++i)
    of << vLines[i] << std::endl;

Or an iterator:

for (auto it = vLines.begin(); it != vLines.end(); ++it)
    of << *it << std::endl;

You will now output all elements in your std::vector to your std::ofstream as well as properly handle situations where there are no elements.

Tas
  • 7,023
  • 3
  • 36
  • 51