我正在尝试使用带有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;
这里有什么问题?
答案 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;
}