Hi I'd like to ask how to parse multiple floats, separated by "/" and spaces, from a string.
嗨,我想问一下如何从字符串中解析多个浮点数,用“/”和空格分隔。
The text format from the file is "f 1/1/1 2/2/2 3/3/3 4/4/4" I need to parse every integer from this line of text into several int variables, which are then used to construct a "face" object(see below).
文件中的文本格式是“f 1/1/1 2/2/2 3/3/3 4/4/4”我需要将这行文本中的每个整数解析成几个int变量,然后使用这些变量构造一个“面子”对象(见下文)。
int a(0),b(0),c(0),d(0),e(0);
int t[4]={0,0,0,0};
//parsing code goes here
faces.push_back(new face(b,a,c,d,e,t[0],t[1],t[2],t[3],currentMaterial));
I could do it with sscanf(), but I've been warn away from that by my uni lecturer, so I am looking for an alternative. I am also not allowed other 3rd party libraries, including boost.
我可以用sscanf()做到这一点,但我已经被我的uni讲师警告过了,所以我正在寻找另一种选择。我也不允许其他第三方库,包括boost。
Regular expressions and parsing with stringstream() have been mentioned, but I don't really know much about either, and would appreciate some advice.
已经提到了正则表达式和使用stringstream()进行解析,但我对这两者都不太了解,并且会很感激一些建议。
4 个解决方案
#1
1
If you're reading the file with std::ifstream, there's no need for std::istringstream in the first place (although using the two is very similar because they inherit from the same base class). Here's how to do it with std::ifstream:
如果你正在使用std :: ifstream读取文件,那么首先不需要std :: istringstream(尽管使用两者非常相似,因为它们从相同的基类继承)。以下是使用std :: ifstream的方法:
ifstream ifs("Your file.txt");
vector<int> numbers;
while (ifs)
{
while (ifs.peek() == ' ' || ifs.peek() == '/')
ifs.get();
int number;
if (ifs >> number)
numbers.push_back(number);
}
#2
1
Taking into account your example f 1/1/1 2/2/2 3/3/3 4/4/4
what you need to read is: char int char int char int int char int char int int char int char int
考虑到您的示例f 1/1/1 2/2/2 3/3/3 4/4/4您需要阅读的内容是:char int char int char int int char int char int int char int char int
To do this:
去做这个:
istringstream is(str);
istringstream是(str);
char f, c;
int d[12];
bool success = (is >> f) && (f == 'f')
&& (is >> d[0]) && (is >> c) && (c == '/')
&& (is >> d[1]) && (is >> c) && (c == '/') &&
..... && (is >> d[11]);
#3
1
The way I would do this is to change the interpretation of space to include the other separators. If I were to get fancy I would use different std::ostream
objects, each with a std::ctype<char>
facet set up to deal with one separator, and use a shared std::streambuf
.
我这样做的方法是改变空间的解释以包括其他分隔符。如果我想要使用,我将使用不同的std :: ostream对象,每个对象都设置为std :: ctype
If you want to make the use of separators explicit you could instead use a suitable manipulator to skip the separator or, if it absent, indicate failure:
如果您想明确使用分隔符,则可以使用合适的操纵器跳过分隔符,如果不存在则表示失败:
template <char Sep>
std::istream& sep(std::istream& in) {
if ((in >> std::ws).peek() != std::to_int_type(Sep)) {
in.setstate(std::ios_base::failbit);
}
else {
in.ignore();
}
return in;
}
std::istream& (* const slash)(std::istream&) = Sep<'/'>;
The code isn't tested and type on a mobile device, i.e., probably contains small errors. You'd read data like this:
代码未在移动设备上进行测试和键入,即可能包含小错误。你会读到这样的数据:
if (in >> v1 >> v2 >> slash >> v3 /*...*/) {
deal_with_input(v1, v2, v3);
}
Note: the above use assumes input as
注意:上面的用法假定输入为
1.0 2.0/3.0
i.e. a space after the first value and a slash after the second value.
即第一个值后的空格和第二个值后的斜杠。
#4
0
You can use boost::split.
你可以使用boost :: split。
Sample example is:
示例示例如下:
string line("test\ttest2\ttest3");
vector<string> strs;
boost::split(strs,line,boost::is_any_of("\t"));
cout << "* size of the vector: " << strs.size() << endl;
for (size_t i = 0; i < strs.size(); i++)
cout << strs[i] << endl;
more information here:
更多信息:
http://www.boost.org/doc/libs/1_51_0/doc/html/string_algo.html
http://www.boost.org/doc/libs/1_51_0/doc/html/string_algo.html
and also related:
还有关:
Splitting the string using boost::algorithm::split
使用boost :: algorithm :: split拆分字符串
#1
1
If you're reading the file with std::ifstream, there's no need for std::istringstream in the first place (although using the two is very similar because they inherit from the same base class). Here's how to do it with std::ifstream:
如果你正在使用std :: ifstream读取文件,那么首先不需要std :: istringstream(尽管使用两者非常相似,因为它们从相同的基类继承)。以下是使用std :: ifstream的方法:
ifstream ifs("Your file.txt");
vector<int> numbers;
while (ifs)
{
while (ifs.peek() == ' ' || ifs.peek() == '/')
ifs.get();
int number;
if (ifs >> number)
numbers.push_back(number);
}
#2
1
Taking into account your example f 1/1/1 2/2/2 3/3/3 4/4/4
what you need to read is: char int char int char int int char int char int int char int char int
考虑到您的示例f 1/1/1 2/2/2 3/3/3 4/4/4您需要阅读的内容是:char int char int char int int char int char int int char int char int
To do this:
去做这个:
istringstream is(str);
istringstream是(str);
char f, c;
int d[12];
bool success = (is >> f) && (f == 'f')
&& (is >> d[0]) && (is >> c) && (c == '/')
&& (is >> d[1]) && (is >> c) && (c == '/') &&
..... && (is >> d[11]);
#3
1
The way I would do this is to change the interpretation of space to include the other separators. If I were to get fancy I would use different std::ostream
objects, each with a std::ctype<char>
facet set up to deal with one separator, and use a shared std::streambuf
.
我这样做的方法是改变空间的解释以包括其他分隔符。如果我想要使用,我将使用不同的std :: ostream对象,每个对象都设置为std :: ctype
If you want to make the use of separators explicit you could instead use a suitable manipulator to skip the separator or, if it absent, indicate failure:
如果您想明确使用分隔符,则可以使用合适的操纵器跳过分隔符,如果不存在则表示失败:
template <char Sep>
std::istream& sep(std::istream& in) {
if ((in >> std::ws).peek() != std::to_int_type(Sep)) {
in.setstate(std::ios_base::failbit);
}
else {
in.ignore();
}
return in;
}
std::istream& (* const slash)(std::istream&) = Sep<'/'>;
The code isn't tested and type on a mobile device, i.e., probably contains small errors. You'd read data like this:
代码未在移动设备上进行测试和键入,即可能包含小错误。你会读到这样的数据:
if (in >> v1 >> v2 >> slash >> v3 /*...*/) {
deal_with_input(v1, v2, v3);
}
Note: the above use assumes input as
注意:上面的用法假定输入为
1.0 2.0/3.0
i.e. a space after the first value and a slash after the second value.
即第一个值后的空格和第二个值后的斜杠。
#4
0
You can use boost::split.
你可以使用boost :: split。
Sample example is:
示例示例如下:
string line("test\ttest2\ttest3");
vector<string> strs;
boost::split(strs,line,boost::is_any_of("\t"));
cout << "* size of the vector: " << strs.size() << endl;
for (size_t i = 0; i < strs.size(); i++)
cout << strs[i] << endl;
more information here:
更多信息:
http://www.boost.org/doc/libs/1_51_0/doc/html/string_algo.html
http://www.boost.org/doc/libs/1_51_0/doc/html/string_algo.html
and also related:
还有关:
Splitting the string using boost::algorithm::split
使用boost :: algorithm :: split拆分字符串