读取输入文件的一部分 我想读一个C++中的输入文件,其中的结构(或缺少)将是一系列文本=数字的行,例如
我想把电话号码弄出去,把其余的都扔掉。数字可以是整数也可以是双精度的,但我知道它们是一个还是另一个 我还想读它,比如读取输入文件的一部分 我想读一个C++中的输入文件,其中的结构(或缺少)将是一系列文本=数字的行,例如,c++,parsing,file-io,C++,Parsing,File Io,我想把电话号码弄出去,把其余的都扔掉。数字可以是整数也可以是双精度的,但我知道它们是一个还是另一个 我还想读它,比如 input1 = 10 input2=4 set1 =1.2 set2= 1.e3 以便对用户更加健壮。我认为这意味着它不应该是格式化的红色 不管怎样,有没有聪明的方法 我已经尝试了以下方法,但对我所做的事情了解甚少,所以结果正如预期的那样。。。没有成功 #include <stdio.h> #include <stdlib.h>
input1 = 10
input2=4
set1 =1.2
set2= 1.e3
以便对用户更加健壮。我认为这意味着它不应该是格式化的红色
不管怎样,有没有聪明的方法
我已经尝试了以下方法,但对我所做的事情了解甚少,所以结果正如预期的那样。。。没有成功
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <boost/lexical_cast.hpp>
#include <string>
using namespace std;
using namespace boost;
int main(){
string tmp;
char temp[100];
int i,j,k;
ifstream InFile("input.dat");
//strtol
InFile.getline(temp,100);
k=strtol(temp,0,10);
cout << k << endl;
//lexical_cast
InFile.getline(temp,100);
j = lexical_cast<int>(temp);
cout << j << endl;
//Direct read
InFile >> tmp >> i;
cout << i << endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间boost;
int main(){
串tmp;
炭温度[100];
int i,j,k;
ifstream infle(“input.dat”);
//斯特托
填充线(温度,100);
k=标准温度(温度,0,10);
我不能;
coutC FTW(修改为处理双打)
#包括
int
主要()
{
双数;
而(!feof(stdin))
如果(1==fscanf(stdin,%*[^=]=%lf,&num))
printf(“%g\n”,num);
返回0;
}
我做对了吗:你取下这行代码,从中提取数字并打印出来(或者在其他地方使用它,无论什么)?如果是这样,你可以使用字符串函数和istringstream:
//these are your codes, removing some though
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
//adding
#include <sstream>
using namespace std;
int main()
{
string line="", extract="";
int placeofop=0, input;
ifstream InFile("input.dat");
while(!InFile.eof())
{
getline(InFile, line);
placeofop = line.find("=");
extract = line.substr(placeofop, (line.length()-placeofop));
istringstream trythis(extract);
trythis >> input;
cout << input << endl;
}
return 0;
}
//这些是您的代码,但删除了一些
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//添加
#包括
使用名称空间std;
int main()
{
字符串行=”,提取=”;
int-placeofop=0,输入;
ifstream infle(“input.dat”);
而(!infle.eof())
{
getline(填充,行);
placeofop=line.find(“=”);
extract=line.substr(placeofop,(line.length()-placeofop));
istringstream trythis(提取物);
尝试此>>输入;
cout>和评论中的一样;我一直在做的事情……现在没有出现编译错误。在我的脑海中:
vector<double> vals(istream &in) {
vector<double> r;
string line;
while (getline(f, line)) {
const size_t eq = line.find('=');
if (eq != string::npos) {
istringstream ss(line.substr(eq + 1));
double d = 0;
ss >> d;
if (ss) r.push_back(d);
else throw "Line contains no value";
}
else {
throw "Line contains no =";
}
}
return r;
}
int main(int argc, char *argv[]) {
vector<double> vs = vals(ifstream(argv[1]));
}
向量VAL(istream&in){
向量r;
弦线;
while(getline(f,line)){
常量大小=line.find('=');
if(eq!=字符串::npos){
istringstream ss(行substr(等式+1));
双d=0;
ss>>d;
如果(ss)r.向后推(d);
否则抛出“行不包含值”;
}
否则{
抛出“行包含否=”;
}
}
返回r;
}
int main(int argc,char*argv[]){
向量vs=VAL(ifstream(argv[1]);
}
以下是我最快的STL解决方案:
#include <fstream>
#include <list>
#include <locale>
void foo()
{
std::fstream f("c:\\temp\\foo.txt", std::ios_base::in);
std::list<double> numbers;
while (!f.eof())
{
int c = f.get();
if (std::isdigit(c, std::locale::classic()) ||
c == '+' ||
c == '-' ||
c == '.')
{
f.putback(c);
double val;
f >> val;
if (f.fail()) {
f.clear(f.eof() ? std::ios_base::eofbit : std::ios_base::goodbit);
continue;
}
else
{
numbers.push_back(val);
}
}
}
}
#包括
#包括
#包括
void foo()
{
std::fstream f(“c:\\temp\\foo.txt”,std::ios\u base::in);
std::列表编号;
而(!f.eof())
{
int c=f.get();
if(std::isdigit(c,std::locale::classic())||
c=='+'||
c=='-'||
c=='。)
{
f、 倒退(c);
双val;
f>>val;
if(f.fail()){
f、 清除(f.eof()?std::ios_base::eofbit:std::ios_base::goodbit);
继续;
}
其他的
{
数字。推回(val);
}
}
}
}
<代码> > p>刚刚测试过…它是有效的,不需要C++标准库之外的任何东西。< /P>
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
#include <sstream>
using namespace std; // just because this is an example...
static void print(const pair<string, double> &p)
{
cout << p.first << " = " << p.second << "\n";
}
static double to_double(const string &s)
{
double value = 0;
istringstream is(s);
is >> value;
return value;
}
static string trim(const string &s)
{
size_t b = 0;
size_t e = s.size();
while (b < e && isspace(s[b])) ++b;
while (e > b && isspace(s[e-1])) --e;
return s.substr(b, e - b);
}
static void readINI(istream &is, map<string, double> &values)
{
string key;
string value;
while (getline(is, key, '='))
{
getline(is, value, '\n');
values.insert(make_pair(trim(key), to_double(value)));
}
}
int main()
{
map<string, double> values;
readINI(cin, values);
for_each(values.begin(), values.end(), print);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;//仅仅因为这是一个示例。。。
静态无效打印(常数对和p)
{
不能一次只读一行。
然后在“=”符号上拆分每一行。使用流功能完成其余部分
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::ifstream data("input.dat");
std::string line;
while(std::getline(data,line))
{
std::stringstream str(line);
std::string text;
std::getline(str,text,'=');
double value;
str >> value;
}
}
#包括
#包括
#包括
#包括
int main()
{
std::ifstream数据(“input.dat”);
std::字符串行;
while(std::getline(数据,行))
{
std::stringstream str(行);
std::字符串文本;
std::getline(str,text,'=');
双重价值;
str>>值;
}
}
使用错误检查:
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::ifstream data("input.dat");
std::string line;
while(std::getline(data,line))
{
std::stringstream str(line);
std::string text;
double value;
if ((std::getline(str,text,'=')) && (str >> value))
{
// Happy Days..
// Do processing.
continue; // To start next iteration of loop.
}
// If we get here. An error occurred.
// By doing nothing the line will be ignored.
// Maybe just log an error.
}
}
#包括
#包括
#包括
#包括
int main()
{
std::ifstream数据(“input.dat”);
std::字符串行;
while(std::getline(数据,行))
{
std::stringstream str(行);
std::字符串文本;
双重价值;
if((std::getline(str,text,'=')&&(str>>值))
{
//快乐的日子。。
//进行处理。
continue;//开始循环的下一次迭代。
}
//如果我们到了这里,发生了一个错误。
//如果不采取任何措施,该行将被忽略。
//也许只是记录一个错误。
}
}
既然您已经在使用boost和词法转换,只需在启用token\u compress的情况下,将每一行解析为1个2元素向量
下面的代码演示了解析过程,但跳过了数字转换,这可以通过boost词法转换轻松解决
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <vector>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/foreach.hpp>
using std::string;
using std::cout;
using std::ifstream;
using std::stringstream;
using std::vector;
std::string file_to_string()
{
ifstream data("data.txt");
stringstream s;
s << data.rdbuf();
return s.str();
}
void print_parameter(vector<string>& v)
{
cout << v_para[0];
cout << "=";
cout << v_para[1];
cout << std::endl;
}
vector<string> string_to_lines(const string& s)
{
return v_lines;
}
int main()
{
vector<string> v_lines;
boost::split(v_lines, file_to_string(), boost::is_any_of("\n"), boost::token_compress_on);
vector<string> v_para;
BOOST_FOREACH(string& line, v_lines)
{
if(line.empty()) continue;
boost::split(v_para, line, boost::is_any_of(" ="), boost::token_compress_on);
// test it
print_parameter(v_para);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用std::string;
使用std::cout;
使用std::ifstream;
使用std::stringstream;
使用std::vector;
std::字符串文件\u到\u字符串()
{
ifstream数据(“data.txt”);
细绳;
如果你正在设计这种格式,我建议你采用这种格式。
轻量级syntaxed INI格式包括在您的情况下可能需要或可能不需要的部分(允许您在格式中有更多的结构):
即
此wikipedia页面上的外部链接列出了许多库,可用于处理这些类型的文件,这些文件扩展/替换Windows API中的基本GetPrivateProfileString函数并支持其他平台。
其中大多数将处理填充=符号的空格(或至少在=之前),因为=之后的空格可能是有意/重要的。
如果您不希望,这些库中的某些库还可以选择省略[sections]
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::ifstream data("input.dat");
std::string line;
while(std::getline(data,line))
{
std::stringstream str(line);
std::string text;
double value;
if ((std::getline(str,text,'=')) && (str >> value))
{
// Happy Days..
// Do processing.
continue; // To start next iteration of loop.
}
// If we get here. An error occurred.
// By doing nothing the line will be ignored.
// Maybe just log an error.
}
}
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <vector>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/foreach.hpp>
using std::string;
using std::cout;
using std::ifstream;
using std::stringstream;
using std::vector;
std::string file_to_string()
{
ifstream data("data.txt");
stringstream s;
s << data.rdbuf();
return s.str();
}
void print_parameter(vector<string>& v)
{
cout << v_para[0];
cout << "=";
cout << v_para[1];
cout << std::endl;
}
vector<string> string_to_lines(const string& s)
{
return v_lines;
}
int main()
{
vector<string> v_lines;
boost::split(v_lines, file_to_string(), boost::is_any_of("\n"), boost::token_compress_on);
vector<string> v_para;
BOOST_FOREACH(string& line, v_lines)
{
if(line.empty()) continue;
boost::split(v_para, line, boost::is_any_of(" ="), boost::token_compress_on);
// test it
print_parameter(v_para);
}
}
[section_1]
variable_1=value1
variable_2=999
[sectionA]
variable_A=value A
variable_B=111
#include <fstream>
#include <string>
#include <boost/spirit.hpp>
using namespace std;
using namespace boost::spirit;
int main()
{
ifstream data("input.dat");
string line;
vector<double> numbers;
while(getline(data,line))
{
parse(line.c_str(),
*(+~ch_p('=') >> ch_p('=') >> real_p[push_back_a(numbers)]),
space_p);
}
}