我有一个输入文件。它包含许多输入值。如果一个对象的输入是这样的:
hss cscf "serving cscf" 32.5 ims 112.134
(注:当一个对象的变量需要多字串时,我用“....”,单字串不带引号)
如何使用 ifstream 读取它?(我搜索了谷歌但没有找到。)
我尝试使用 getline 阅读整行,但在确定是单个单词还是多单词输入时再次卡住了!
请为此提出一些建议。
希望这个程序可以帮助你
int main()
{
fstream fstr;
fstr.open("abc.txt",ios::in);
string str;
vector<string> Vec;
while(getline(fstr,str))
{
char* pch;
bool flag = false;
string strTmp;
int counter=0;
pch = strtok (const_cast<char*>(str.c_str())," ");
while (pch != NULL)
{
//this "is a" sample
if(pch[0]=='\"')
{
flag = true;
strTmp = strTmp + " " + string(pch).substr(1,strlen(pch)-1);
}
else
{
if(flag==true)
{
if(pch[strlen(pch)-1]=='\"')
{
flag=false;
strTmp = strTmp + " " + string(pch).substr(0,strlen(pch)-1);
Vec.push_back(strTmp);
}
else
{
strTmp = strTmp + " " + pch;
}
}
else
{
Vec.push_back(pch);
}
}
pch = strtok(NULL," ");
}
}
for(auto itr = Vec.begin();itr!=Vec.end();itr++)
{
cout<<*itr<<endl;
}
getchar();
}
只是提供一个总结
提取每一行并使用strtok
空格作为分隔符获取单词。(这里,即使是引号中的单词也会被提取为单个单词,而不会将它们视为多个单词。
对于提取的每个单词,检查它是否以引号开头。如果否,则将其添加到向量中,否则将其添加到临时字符串并启用标志。
现在,检查每个单词是否以引号结尾以及是否设置了标志。如果两者都满足,则将整个临时字符串添加到 vecor 或继续将单词添加到临时字符串。
总而言之,这会在临时字符串中保留引号中的单词,并直接将单个单词添加到向量中。当引号结束时,它也会将临时字符串添加到向量中。
由于您正在尝试解析来自文件流的输入,并且您正在处理多个单词的可能性,如果您希望使用通用支持和完全可定制的支持 - 即您想要解析任何类型的输入,那么你需要正则表达式。
您可以使用 C++11 的正则表达式,但gcc 目前不支持。
因此,一种解决方案是使用适用于标准 c++98、c++03 和 c++0x 的 boost C++ 库:
#include <string>
#include <iostream>
#include <cstdlib>
#include <boost/regex.hpp>
using namespace std;
int main() {
string text = "hss cscf \"serving\" 32.5 ims 112.134";
boost::regex e("(\\w+)\\s(\\w+)\\s\"(\\w+\\s?)+\"\\s([0-9]+(\\.[0-9][0-9]?)?)\\s(\\w+)\\s([0-9]+(\\.[0-9][0-9]?)?)");
boost::sregex_token_iterator iter(text.begin(), text.end(), e, 0);
boost::sregex_token_iterator end;
for(; iter != end; ++iter) {
std::cout << *iter << std::endl;
}
return 0;
}
您可以通过以下方式使用 gcc(我使用 gcc-4.7.2)编译它:
g++ {filename} -std={language version} -I{your boost install location} -L{your boost library location} -o {output filename} {your boost library location}/libboost_regex.a
至于为什么可怕的长正则表达式,如果您希望使用正则表达式支持完整的十进制解析,那么上面的内容将适用于以下字符串:
"hss cscf \"serving\" 32.5 ims 112.134"
"hss cscf \"serving more than one\" 32.5 ims 112.134"
"hss cscf \"serving\" 32 ims 112"
参考:
提升正则表达式: http: //www.solarix.ru/for_developers/api/regex-en.html