0

I have a text file with the following information in it:

    2B,410,AER,2965,KZN,2990,,0,CR2
2B,410,ASF,2966,KZN,2990,,0,CR2
2B,410,ASF,2966,MRV,2962,,0,CR2
2B,410,CEK,2968,KZN,2990,,0,CR2
2B,410,CEK,2968,OVB,4078,,0,CR2
2B,410,DME,4029,KZN,2990,,0,CR2
2B,410,DME,4029,NBC,6969,,0,CR2
2B,410,DME,4029,TGK,\N,,0,CR2

(it is airline route info)

I'm trying to loop through the file and extract each line into a char* - simple right?

Well, yes, it's simple but not when you've completely forgotten how to write successful i/o operations! :)

My code goes a little like:

char * FSXController::readLine(int offset, FileLookupFlag flag)
{
    // Storage Buffer
    char buffer[50];
    std::streampos sPos(offset);

    try
    {
        // Init stream
        if (!m_ifs.is_open())
            m_ifs.open(".\\Assets\\routes.txt", std::fstream::in);
    }
    catch (int errorCode)
    {
        showException(errorCode);
        return nullptr;
    }

    // Set stream to read input line
    m_ifs.getline(buffer, 50);

    // Close stream if no multiple selection required
    if (flag == FileLookupFlag::single)
        m_ifs.close();

    return buffer;

}

Where m_ifs is my ifStream object.

The problem is that when I breakpoint my code after the getline() operation, I notice that 'buffer' has not changed?

I know it is something simple, but please could someone shed some light onto this - I'm tearing my forgetful hair out! :)

P.S: I never finished writing the exception handling so it is pretty useless right now!

Thanks

Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
Catch_0x16
  • 187
  • 1
  • 4
  • 13
  • 1
    You return a pointer to a local variable. Local variables go out of scope when a function exits. Why aren't you using [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string) and [`std::getline`](http://en.cppreference.com/w/cpp/string/basic_string/getline)? – Some programmer dude Aug 29 '16 at 18:05
  • c-style strings should be avoided in c++. Is there a reason you explicitly using a `char buffer` instead of a `std::string` ? – KostasRim Aug 29 '16 at 18:06
  • Also, what would you like to do for each line? What is the final data structure you want to have and to populate from the file? – Khalil Khalaf Aug 29 '16 at 18:09
  • Ensure that you were able to successfully open the file. – AndyG Aug 29 '16 at 18:12
  • Thanks for the super quick replies! I wanted to handle the data in an array-like format (c string) so that I could go through and remove the commas, truncate stuff etc. In my mind this would be easier in this format, but may change as I get something working. My intention for each line is to extract data between the commas for use in initializing structs that are formed around that data. – Catch_0x16 Aug 29 '16 at 18:12
  • 1
    @GuyLeonardThomas using a `std::string` is easier... – KostasRim Aug 29 '16 at 18:13
  • @AndyG How would you recommend doing this? I feel this is the most likely cause but no exception was thrown. – Catch_0x16 Aug 29 '16 at 18:14
  • @KostasRim Ok, I'll bow to your experience and change it now, thanks :) - Oh also, I think getline() requires a char* – Catch_0x16 Aug 29 '16 at 18:15
  • @GuyLeonardThomas no `getline()` works with `std::string` check my answer – KostasRim Aug 29 '16 at 18:17
  • related: http://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c – NathanOliver Aug 29 '16 at 18:20
  • @GuyLeonardThomas: You can check the state of the stream. It has an implicit conversion to `bool`, so something like `if(!m_ifs){//Error}` after `getline` is called. When you switch to a string, you can use `getline` directly: `if (!getline(m_ifs, myString)){//error}` – AndyG Aug 29 '16 at 18:24
  • @AndyG Ah-ha thanks dude, yes confirmed, the file isn't being opened... which is odd as it is definitely in that folder :/ – Catch_0x16 Aug 29 '16 at 18:46
  • @GuyLeonardThomas: It will search paths as relative by default. Try an absolute path. Failing that, check that you have read permissions on the file. – AndyG Aug 29 '16 at 18:50
  • Tried all, still won't open - my my this is frustrating! :) – Catch_0x16 Aug 29 '16 at 19:03
  • Can you post the code for how you're trying to open? – AndyG Aug 30 '16 at 10:06

2 Answers2

3

Here is a fix with some important c++ libraries you may want to learn, and what I believe a better solution. Since you just need your final result to be strings:

// A program to read a file to a vector of strings 
// - Each line is a string element of a vector container
#include <fstream>
#include <string>
#include <vector>

// ..

std::vector<std::string> ReadTheWholeFile()
{
    std::vector<std::string> MyVector;
    std::string JustPlaceHolderString;
    std::ifstream InFile;

    InFile.open("YourText.txt"); // or the full path of a text file

    if (InFile.is_open())
        while (std::getline(InFile, PlaceHolderStr));
            MyVector.push_back(PlaceHolderStr);

    InFile.close(); // we usually finish what we start - but not needed
    return MyVector;
}

int main()
{
    // result
    std::vector<std::string> MyResult = ReadTheWholeFile();

    return 0;
}
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
1

There are two basic problems with your code:

  1. You are returning a local variable. The statement return buffer; results in a dangling pointer.

  2. You are using a char buffer. C-style strings are discouraged in c++, you should always prefer std::string instead.

A far better approach is this:

string FSXController::readLine(int offset, FileLookupFlag flag) {
    string line;
    //your code here 

    getline(m_ifs, line) //or while(getline(my_ifs, line)){ //code here } to read multiple lines
    //rest of your code
    return line;
}

More information about std::string can be found here

KostasRim
  • 2,053
  • 1
  • 16
  • 32
  • Just checking the code now, will upvote when I've got it working :) – Catch_0x16 Aug 29 '16 at 18:21
  • @GuyLeonardThomas let me know if you have any problems – KostasRim Aug 29 '16 at 18:25
  • Still having issues where the file isn't being opened, (even with absolute path) can you think of any reasons the file wouldn't open? Or that getLine would return false?) – Catch_0x16 Aug 29 '16 at 19:13
  • @GuyLeonardThomas if the file is on the same directory as the program you should not have any problems. The usual pattern is to open the file with an ifstream object and then read it line by line using the getline() function – KostasRim Aug 29 '16 at 19:25