-1

I want to be able to go line by line through this text file and grab parts of it. For example,

Albert, Fred
4541231234
8888 Avenue Drive

Doe, John
6191231234
1234 State Street

Smith, Mike
8791231234
0987 Drive Avenue

I need to grab Albert and store it as the last name. Fred as the first name (excluding the ", ", and the phone number and address.

Searching through threads, I found a little help and this is what I have.

void AddressBook::readFile(Contact * phoneBook[])
{

    std::string line, line1, line2, line3, line4;
    std::ifstream myFile("fileName.txt");
    std::string name, fName, lName, phoneNumber, address;

    if (!myFile.is_open())
    {
        std::cout << "File failed to open." << std::endl;
        return;
    }

    while (true)
    {
        if (!getline(myFile, line1)) 
        {
            break;
        }

        if (!getline(myFile, line2)) //need to parse into lName and fName
        {
            break;
        }

        if (!getline(myFile, line3))
        {
            break;
        }

        if (!getline(myFile, line4))
        {
            break;
        }

        addContact(line1, line2, line3, line4);
    }
}

As you can see, this code only grabs the entire line. How can I stop at the comma, store it into a last name variable, and continue to the first name?

  • I guess C++ doesn't have a built in `string.Spilt()`, but this post shows a few ways to make one (https://stackoverflow.com/questions/16286095/similar-function-to-javas-string-split-in-c), so, after successfully creating the `Split()` you get the line and split on commas, then populate your variables. – Ryan Wilson Mar 26 '19 at 17:06
  • `std::getline` has a third parameter that is defaulted to `'\n'` to split streams on line endings. You can replace the default with any character you want, including `','`. So you take `line1`, use it as the basis for a `std::stringstream` (`std::istringstream strm(line1);`) and then you can `std::getline(strm, lastname, ',');` That leaves you with a space and then the firstname in the stream, ignore the space and getline to the end of the stream to get the first name. – user4581301 Mar 26 '19 at 17:10

3 Answers3

1

I think you can use the substr function, like that:

line2_1 = line2.substr(0, line2.find(','))
line2_2 = line2.substr(line2.find(',')+2, line2.length())

The +2 is because you have a comma (+1) and a space after the comma (+1).

user4581301
  • 33,082
  • 7
  • 33
  • 54
Sheltine
  • 31
  • 7
  • 1
    Close. One small correction (and an optimization). `substr`'s second parameter is defaulted to the stop collecting at the end of the string AND is the count of characters in the substring, not the position of the end of the substring in the original string. Doesn't matter here because substring will stop when it hits the end of the source string anyway. If you cache the result from `line2.find(',')` you won't have to call it twice. Give `auto loc = line2.find(','); line2_1 = line2.substr(0, loc); line2_2 = line2.substr(line2.find(',')+1);` a try. – user4581301 Mar 26 '19 at 17:32
  • 1
    this almost works perfectly. The only issue is that it adds a space before the first name each time it updates the file and I have no clue why. `lastName, [space] firstName` –  Mar 26 '19 at 17:40
  • 1
    @TylerLe You're right. The +1 in `line2.substr(line2.find(',')+1, line2.length())` should be a +2. The +1 skips the comma, but leaves the space. – user4581301 Mar 26 '19 at 18:00
1

std::getline has an overload with a third parameter that allows you to split streams on whatever character you wish to use instead of a line ending. So you take line1, use it as the basis for a std::istringstream

std::istringstream strm(line1);

and then you can

std::getline(strm, lastname, ','); 

That leaves you with a space and then the firstname in the stream, ignore the space and getline to the end of the stream to get the first name.

All together, it should look something like

std::istringstream strm(line1);
std::getline(strm, lastname, ','); 
strm.ignore();
std::getline(strm, firstname); 
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 1
    Technically, `getline()` is [overloaded](http://www.cplusplus.com/reference/string/string/getline/), not given a default parameter. That's really picky though. –  Mar 26 '19 at 17:34
  • You are correct. Thank you. In C++ exactness always counts sooner or later. – user4581301 Mar 26 '19 at 17:40
  • Thank you for the concise answer! It worked just how I wanted it to. –  Mar 26 '19 at 17:50
1

You're missing a delimiter.

Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).

getline() is overloaded in C++, so you can use it like you are or you can use it like this:

getline(myFile, line1,',')

This will tell getline to use a newline character as a delimiter, not a space.