2

So currently I am working on an assignment, and for a section of it I need to be able to read a .txt file into a linked list of type char. I was already confused trying to do this, so I set out on a different path and decided to try to copy the text from the file into a char array, and then one by one copy the values in the array into the linked list.

So far I have my program compiling and running up to a certain point, before I receive the error Segmentation fault (core dumped).

The code for reading the file is as follow:

void readFile(list<char> &originList, string fileName){
    ifstream fileInput;
    fileInput.open(fileName.c_str());

    int arraySize = fileInput.gcount();
    char tempHold[arraySize];

    if (!fileInput) {
        cout << "Can't open file: " << fileName << "\n";
    } else {
        string contents((istreambuf_iterator<char>(fileInput)), istreambuf_iterator<char>());
        strcpy (tempHold, contents.c_str());

        for (int x = 0; x < fileInput.gcount(); x++) {
            originList.push_back(tempHold[x]);
        }

   }

   fileInput.close();
}

Also to add some context, using cout I determined that the code stops running, instead presenting the error, at the following point:

strcpy (tempHold, contents.data());

Also, I am not 100% on how exactly they work, only a loose idea to be honest. I mostly sourced the idea from this Stack Overflow question, How to copy a .txt file to a char array in c++, but got confused somewhere a long the way.

Thanks in advance for any help you can provide.

Community
  • 1
  • 1
  • Use the method in this SO question: http://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line to read each character from the file. But instead of putting it in an array first, just `push_back` each `char`. – Jonny Henly May 05 '16 at 08:54

2 Answers2

1

istream::gcount returns the number of characters extracted by the last unformatted input operation performed on the object. Since you did not read anything from the file, you should get something wrong.

Call, for example, istream.getline(); before calling gcount()

GMichael
  • 2,604
  • 1
  • 18
  • 27
  • The first part of your answer is correct but the second part will just lead to another question if his file contains more than one line and he doesn't reset the file pointer back to the beginning of the file. – Jonny Henly May 05 '16 at 08:48
0

Like my comment to your question says, read each character from the file and add it to the list.

void readFile(list<char> &originList, string fileName) {
    ifstream fileInput(fileName.c_str());

    if (!fileInput) {
        cout << "Can't open file: " << fileName << "\n";
    }

    char c;
    while (fileInput.get(c)) {
        originList.push_back(c);
    }

}

Note: while (fileInput.get(c)) This reads the character and returns the stream. When a stream is used as a bool value it checks to see if the stream is valid. Valid means eof() and bad() are both false. - From a comment to the answer to the question linked below.

My answer was adapted from this other Stack Overflow question: Reading from text file until EOF repeats last line

Community
  • 1
  • 1
Jonny Henly
  • 3,725
  • 4
  • 23
  • 41
  • There's no need to call close as is implicitly called by destructor. I would use get, instead of >> (formatted input). Also the file name should be a const char* or a const string&. – zdf May 05 '16 at 09:14
  • @ZDF removed the close, thanks. Why would you need formatted input if you're just reading characters? – Jonny Henly May 05 '16 at 09:17
  • That's why you should use get instead of >> (get is unformatted). – zdf May 05 '16 at 09:18
  • @ZDF Ohh I see what you're saying. I'll change that. – Jonny Henly May 05 '16 at 09:20
  • Oh wow, okay that is a lot better than what I was trying to do! Thank you very much. I do have one last question to this though, I printed out what the list holds and don't see any NULL values or space (' ') values. How would i go about taking these as well? and maybe even '\n' values as well, but not as important. – Mark Macdonald May 05 '16 at 09:23
  • @MarkMacdonald it should be printing space values, I'm not sure how it would print NULL values - perhaps `^@`. I edited the code above to use `while (fileInput.get(c))`, have you run your code using that change? – Jonny Henly May 05 '16 at 09:33
  • 1
    @JonnyHenly Oh yes, sorry my browser must not have refreshed with the `fileInput.get(c)`. I was still using `fileInput >> c`. It works perfectly now, thank you very much for your help :), it was greatly appreciated. – Mark Macdonald May 05 '16 at 09:37