0

I have a problem, when I try getline, instead of scanning a line program chooses to take the whole text. I tried adding delim also I have include string for this, but it still doesn't seem to work. And the vector is just one big string.

void convert_wishlist(ifstream& file, vector<string>& wishlist, int& budget){
    assert(file.is_open());
    string g;
    file>>budget;
    while (!file.fail()) {
        getline(file, g);
        wishlist.push_back(g);
    }
}
  • 3
    The only way I know for `std::getline()` to not stop on a line break is if that line break is a bare-CR (`\r`) rather than a bare-LF (`\n`) or CRLF (`\r\n`). Have you tried specifying `\r` as the line delimiter? `getline(file, g, '\r')` Also, `while (!file.fail()) { getline(file, g); ... }` should be written as `while (getline(file, g)) { ... }` instead. Also, be aware of this issue: [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/) – Remy Lebeau Dec 03 '20 at 18:50
  • 1
    Can we get a [mre]? `getline` be default will stop at the first newline so you'd only read the whole file if there is no `'\n'` character in the file. – NathanOliver Dec 03 '20 at 18:51
  • what is the input? I have seen someone assume that any text that spans several lines has a line break. It was rather similar quesiton, for the solution we need to see the input (and expected and actual output) – 463035818_is_not_a_number Dec 03 '20 at 18:52
  • the text file: 5000 cd A Darker Shade Of White by Navarone sport Skateboard game Mens erger je niet! (only there are new lines after every item) – Liutauras Kuolis Dec 03 '20 at 18:55
  • Thank you Remy this helped!!! – Liutauras Kuolis Dec 03 '20 at 18:58

1 Answers1

0

A while back, I had to write code ready to deal deal with text files coming from either Windows or Linux so I wrote my own version of getline that was ready for either. This has worked for me

template<class CT, class TT, class AT> 
inline
std::basic_istream<CT, TT>& getline(
    std::basic_istream<CT, TT>&    instr,
    std::basic_string<CT, TT, AT>& str)
{
    using is_type                   = std::basic_istream<CT, TT>;
    using sentry_type               = typename is_type::sentry;
    std::ios_base::iostate state    = std::ios_base::goodbit;
    auto changed                    = false;
    const sentry_type sentry(instr, true);

    if (sentry)
    {   
        // State okay, extract characters

        try
        {
            auto sb = instr.rdbuf();
            str.erase();
            const auto delimNL = TT::to_int_type('\n');
            const auto delimCR = TT::to_int_type('\r');
            auto ch            = sb->sgetc();

            for (; ; ch = sb->snextc())
            {
                if (TT::eq_int_type(TT::eof(), ch))
                {   
                    // End of file, quit
                    state |= std::ios::eofbit;
                    break;
                }
                else if (TT::eq_int_type(ch, delimNL))    
                {
                    // Got a newline, discard it and quit.

                    changed = true; // We did read something successfully
                    sb->sbumpc();   // Discard this character
                    break;          // Quit
                }
                else if (TT::eq_int_type(ch, delimCR))
                {   
                    // Got a carriage return.  

                    changed = true; // We did read something successfully
                    sb->sbumpc();   // Discard this character

                    // Next character might be a newline. If so, do the
                    // same for that

                    if (TT::eq_int_type(sb->sgetc(), delimNL))
                        sb->sbumpc();

                    break;          // We are done
                }
                else if(str.max_size() <= str.size())
                {   
                    // String too large, quit

                    state |= std::ios_base::failbit;
                    break;
                }
                else
                {   
                    // Got a character, add it to string

                    str += TT::to_char_type(ch);
                    changed = true;
                }
            }
        }
        catch(...)
        {
            // Some exception.  Set badbit and rethrow

            instr.setstate(std::ios_base::badbit);  
            throw;
        }
    }
}
Joe
  • 2,355
  • 8
  • 24