使用stringstream:仅适用于第一个值

时间:2015-03-04 19:23:38

标签: c++ get stringstream peek

我正在尝试使用带有peek()和get(n)的stringstream。它仅适用于第一个值Name,然后为除除重量之外的所有内容提供空值,该值为0(使用cout打印时)。

    stringstream ss;
    ss.str("John Smith, Toyota, 160, brown blue, orange");
    //Extract into these variables:
    string Name = "" ;
    string car = "" ;
    int weight = 0;
    string hairColor = "";
    string eyeColor = "";
    string favoriteColor = "";





while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            Name += temp;
        }
while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            car += temp;
        }
while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            weight += temp;
        }
while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            hairColor += temp;
        }
while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            eyeColor += temp;
        }
while (ss.peek () != ',')
        {
            char temp;
            ss. get(temp);
            favoriteColor += temp;
        }


cout << "Name is: " << Name << endl;
cout << "car is: " << car << endl;
cout << "weight is: " << weight << endl;
cout << "Hair color is: " << hairColor << endl;
cout << "Eye color is: " << eyeColor << endl;
cout << "Favorite color is: " << favoriteColor << endl;

这里有什么问题?

2 个答案:

答案 0 :(得分:1)

当前的问题是,在第一个循环之后,延续条件是false,因此以下循环中没有一个具有相同的延续条件,可以做任何事情。

但是,提取项目的常用方法是使用getline函数,您可以在其中指定任意分隔符而不是换行符。

正确地做这件事有点过分了:

#include <iomanip>              // std::setw
#include <iostream>
#include <stdexcept>            // std::runtime_error, std::exception
#include <stdlib.h>             // EXIT_FAILURE, EXIT_SUCCESS
#include <sstream>              // std::istringstream
using namespace std;

auto fail( const string& s ) -> bool { throw runtime_error( s ); }

auto get_string( istream& stream, const char delimiter = ',' )
    -> string
{
    while( stream.peek() == ' ' )
    {
        stream.get();
    }
    string result;
    getline( stream, result, delimiter )
        || fail( "get_string: failed to extract text" );
    return result;
}

template< class Type >
auto get( istream& stream, const char delimiter = ',' )
    -> Type
{
    istringstream conversion_stream( get_string( stream, delimiter ) );
    Type result;
    conversion_stream >> result
        || fail( "get: failed to convert text to value" );
    return result;
}

template<>
auto get<string>( istream& stream, const char delimiter )
    -> string
{ return get_string( stream, delimiter ); }

template< class Type >
void display( const char name[], const Type& value )
{
    cout << setw( 15 ) << name << " = " << value << endl;
}

#define DISPLAY( x ) display( #x, x )
void cpp_main()
{
    istringstream data_stream( "John Smith, Toyota, 160, brown, blue, orange" );

    const auto name             = get<string>( data_stream );
    const auto car              = get<string>( data_stream );
    const auto weight           = get<int>( data_stream );
    const auto hairColor        = get<string>( data_stream );
    const auto eyeColor         = get<string>( data_stream );
    const auto favoriteColor    = get<string>( data_stream );

    DISPLAY( name );
    DISPLAY( car );
    DISPLAY( weight );
    DISPLAY( hairColor );
    DISPLAY( eyeColor );
    DISPLAY( favoriteColor );
}

auto main() -> int
{
    try
    {
        cpp_main();
        return EXIT_SUCCESS;
    }
    catch( const exception& x )
    {
        cerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}

答案 1 :(得分:0)

ss.peek() == ','在第一个循环结束时变为true。使用std::getline,以便您不会遇到此问题:

if (getline(ss, Name) && getline(ss, car) && ss >> weight && getline((ss >> std::ws).ignore(), hairColor))
{
    cout << "Name is: " << Name << endl;
    cout << "car is: " << car << endl;
    cout << "weight is: " << weight << endl;
    cout << "Hair color is: " << hairColor << endl;
    cout << "Eye color is: " << eyeColor << endl;
    cout << "Favorite color is: " << favoriteColor << endl;
}