我有一堆输入文件,如下所示:
(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)
我需要编写一个函数,一次解析这些输入一个数字,所以我需要能够用数字分隔输入,例如:8,然后是7,然后是15,然后是0,再是0,等等
我到目前为止唯一想到的方法是使用istream.get()返回下一个字符的ASCII码,我可以通过将其转换为char来转换回其字符格式。然后我会检查字符是否是数字(因此括号被忽略)但这样,任何双(或三)位数字一次只读一位数。
实现这一目标的最佳方式是什么?
顺便说一句,我必须使用istream。这是规范的一部分,我不允许改变
由于
答案 0 :(得分:7)
这是一个解决方案:
struct integer_only: std::ctype<char>
{
integer_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc['9'+1], std::ctype_base::digit);
return &rc[0];
}
};
int main() {
std::cin.imbue(std::locale(std::locale(), new integer_only()));
std::istream_iterator<int> begin(std::cin);
std::istream_iterator<int> end;
std::vector<int> vints(begin, end);
std::copy(vints.begin(), vints.end(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
输入:
(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)
输出:
8 7 15 0 0 1 0 3 2 0 6 3 1 0 4 1 1 5
在上文中,您必须在成功打开文件后用文件流替换std::cin
,如下所示:
std::ifstream file("file.txt");
file.imbue(std::locale(std::locale(), new integer_only()));
std::istream_iterator<int> begin(file);
std::istream_iterator<int> end;
std::vector<int> vints(begin, end); //container of integers!
这里,vints
是一个包含所有整数的向量。您希望与vints
合作做一些有用的事情。此外,您可以在int*
预期的地方使用它:
void f(int *integers, size_t count) {}
f(&vints[0], vints.size()); //call a function which expects `int*`.
当只读取文件中的单词时,可以应用类似的技巧。这是一个例子:
答案 1 :(得分:3)
以下是一些代码,您可以根据自己的需求进行调整
for (;;)
{
int ch = in.get();
if (ch == EOF)
break;
if (isdigit(ch))
{
int val = ch - '0';
for (;;)
{
ch = in.get();
if (!isdigit(ch))
break;
val *= 10;
val += ch - '0';
}
// do something with val
}
}
这是未经测试的代码。
答案 2 :(得分:2)
尝试阅读一个数字。如果失败,请清除错误状态并尝试读取char
(并忽略它)。重复这两个步骤,直到读取char失败,在这种情况下你处于EOF或真正的失败。
可以通过识别')'进行优化,然后阅读直到'('。
但我不认为这是值得的。
欢呼&amp;第h。,答案 3 :(得分:2)
另一种解决方案:
#include <string>
#include <ostream>
#include <fstream>
#include <iostream>
struct triple
{
long a;
long b;
long c;
};
std::ostream& operator << (std::ostream& os, const triple& value)
{
return os << value.a << "/" << value.b << "/" << value.c;
}
int main()
{
std::ifstream stream("Test.txt");
if (!stream)
{
std::cout << "could not open the file" << std::endl;
}
std::string dummy;
triple value;
while (std::getline(stream, dummy, '(') >> value.a &&
std::getline(stream, dummy, ',') >> value.b &&
std::getline(stream, dummy, ',') >> value.c)
{
std::cout << value << std::endl;
}
}
答案 4 :(得分:1)
int getFirstPos(const string& str)
{
int pos=0,PosHit=0;
bool bfind=false;
if((PosHit=str.find(','))!=string::npos){
if(!bfind) pos=PosHit;
pos=pos>PosHit?PosHit:pos;
bfind=true;
}
if((PosHit=str.find('('))!=string::npos){
if(!bfind) pos=PosHit;
pos=pos>PosHit?PosHit:pos;
bfind=true;
}
if((PosHit=str.find(')'))!=string::npos){
if(!bfind) pos=PosHit;
pos=pos>PosHit?PosHit:pos;
bfind=true;
}
return bfind?pos:string::npos;
}
void main()
{
ifstream ifile("C:\\iStream.txt");
string strLine;
vector<double> vecValue; //store the datas
while(getline(ifile,strLine)){
if(strLine.size()==0)
continue;
int iPos=0;
while((iPos=getFirstPos(strLine))!=string::npos)
strLine[iPos]=' ';
istringstream iStream(strLine);
double dValue=0;
while(iStream>>dValue)
vecValue.push_back(dValue);
}
//output the result!
vector<double>::iterator it;
for (it=vecValue.begin(); it!=vecValue.end() ; ++it){
cout<<setprecision(3)<<*it<<endl;
}
}