C++ 有没有办法打破一个getline?
您可以在循环中使用C++ 有没有办法打破一个getline?,c++,C++,您可以在循环中使用std::getline()读取每一行,然后使用std::find_if()查找该行的第一位数字。这就是拆分字符串的位置。我将把食物名称后面的空格删掉交给你处理 Hamburger 1.89 Cheeseburger 2.29 French Fries 1.59 Onion Rings 1.59 Soda 1.29 Iced Tea 1.29 输出: #include <iostream> #include <sstream
std::getline()
读取每一行,然后使用std::find_if()
查找该行的第一位数字。这就是拆分字符串的位置。我将把食物名称后面的空格删掉交给你处理
Hamburger 1.89
Cheeseburger 2.29
French Fries 1.59
Onion Rings 1.59
Soda 1.29
Iced Tea 1.29
输出:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
int main()
{
using namespace std;
istringstream is(
R"(Hamburger 1.89
Cheeseburger 2.29
French Fries 1.59
Onion Rings 1.59
Soda 24 1.29
Iced Tea free
)");
string line;
while( getline( is, line ) )
{
auto itLineRevEnd = crend( line );
// Find end (reverse begin) of price token.
auto itPriceRevBegin = find_if( crbegin( line ), itLineRevEnd, []( char c ){ return ! isspace( c ); } );
if( itPriceRevBegin != itLineRevEnd )
{
// Find begin (reverse end) of price token.
auto itPriceRevEnd = find_if( itPriceRevBegin, itLineRevEnd, []( char c ){ return isspace( c ); } );
if( itPriceRevEnd != itLineRevEnd )
{
// Find end (reverse begin) of name.
auto itNameRevBegin = find_if( itPriceRevEnd, itLineRevEnd, []( char c ){ return ! isspace( c ); } );
if( itNameRevBegin != itLineRevEnd )
{
// Call reverse_iterator::base() to turn them into forward iterators (otherwise strings would be reversed).
string name( itLineRevEnd.base(), itNameRevBegin.base() );
string price( itPriceRevEnd.base(), itPriceRevBegin.base() );
cout << "\nFood: \"" << name << "\"";
cout << "\nPrice: ";
try
{
double priceNum = stod( price );
cout << priceNum << endl;
}
catch( std::exception& e )
{
// Conversion error or out-of-range.
cout << "ERROR" << endl;
}
}
}
}
}
}
菜单文件是什么样子的?汉堡1.89芝士汉堡2.29薯条1.59洋葱圈1.59苏打水1.29冰茶1.29没有格式化的汉堡1.89是它自己的行,所以每个项目和价格都有它自己的行这个解决方案的一个问题是如果名称本身包含任何数字。更好的方法可能是从每一行的末尾向后查找第一个非-space@harmic感谢您的建议,我添加了第二个示例。
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <cctype>
int main()
{
using namespace std;
istringstream is(
R"(Hamburger 1.89
Cheeseburger 2.29
French Fries 1.59
Onion Rings 1.59
Soda 1.29
Iced Tea 1.29
)");
string s;
while( getline( is, s ) )
{
auto it = find_if( begin( s ), end( s ), []( char c ){ return isdigit( c ); } );
if( it != end( s ) )
{
string name( begin( s ), it );
string price( it, end( s ) );
cout << "\nFood: " << name << "\nPrice: " << price << endl;
}
}
}
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
int main()
{
using namespace std;
istringstream is(
R"(Hamburger 1.89
Cheeseburger 2.29
French Fries 1.59
Onion Rings 1.59
Soda 24 1.29
Iced Tea free
)");
string line;
while( getline( is, line ) )
{
auto itLineRevEnd = crend( line );
// Find end (reverse begin) of price token.
auto itPriceRevBegin = find_if( crbegin( line ), itLineRevEnd, []( char c ){ return ! isspace( c ); } );
if( itPriceRevBegin != itLineRevEnd )
{
// Find begin (reverse end) of price token.
auto itPriceRevEnd = find_if( itPriceRevBegin, itLineRevEnd, []( char c ){ return isspace( c ); } );
if( itPriceRevEnd != itLineRevEnd )
{
// Find end (reverse begin) of name.
auto itNameRevBegin = find_if( itPriceRevEnd, itLineRevEnd, []( char c ){ return ! isspace( c ); } );
if( itNameRevBegin != itLineRevEnd )
{
// Call reverse_iterator::base() to turn them into forward iterators (otherwise strings would be reversed).
string name( itLineRevEnd.base(), itNameRevBegin.base() );
string price( itPriceRevEnd.base(), itPriceRevBegin.base() );
cout << "\nFood: \"" << name << "\"";
cout << "\nPrice: ";
try
{
double priceNum = stod( price );
cout << priceNum << endl;
}
catch( std::exception& e )
{
// Conversion error or out-of-range.
cout << "ERROR" << endl;
}
}
}
}
}
}
Food: "Hamburger"
Price: 1.89
Food: "Cheeseburger"
Price: 2.29
Food: "French Fries"
Price: 1.59
Food: "Onion Rings"
Price: 1.59
Food: "Soda 24"
Price: 1.29
Food: "Iced Tea"
Price: ERROR