处理 space(或制表符)分隔的文件 "like" 和数组 - C++
Treat a space(or tab) separated file "like" and array - C++
我有一个简短的 tab/space 分隔文件(我可以相应地创建它),其结构为
[data00] <space> [data01] <space> [data02] <space> [data03] <newline>
[data10] <space> [data11] <space> [data12] <space> [data13] <newline>
...
第一列代表数字 ID。我创建这个文件是为了将它提供给另一个可执行文件,所以格式是固定的。输入后,可执行文件输出另一个具有类似结构的文件:
[data00] <space> [data01]<newline>
[data10] <space> [data11]<newline>
...
给定一个ID,我需要读取对应的[dataX1]
,对第一个文件中的[dataX3]
进行操作,反馈给可执行文件,进行迭代。
我想到了两种方法:
- 对两个文本文件进行操作 "as if" 它们是数组,因为它们的结构是固定的,但我不知道 function/syntax 要使用什么。这应该是一个小函数,它可以让我通过传递相关的数字 ID 来读取有趣的部分,隐藏所有讨厌的 I/O 代码,因为我可能需要在不同的上下文中重复这个操作很多
- 将第一个文件保存在数组中并通过向其提供流来欺骗可执行文件(这可能吗?可执行文件需要一个文件作为参数)。
我可以轻松地将文件读入数组并每次重新写入文件,但我想避免无用的读写操作,而我每次需要 read/write 只是一个单元格。我现在不知道如何做的是当我通过使用 getline
.
从文本文件中读取整行时如何 stop/identify 感兴趣的位
首先,我们将编写一个函数,根据给定的分隔符拆分输入的字符串。 (在这种情况下,我们将使用 space。)
int split(const std::string& line, const std::string& seperator, std::vector<std::string> * values){
std::string tString = "";
unsigned counter = 0;
for(unsigned l = 0; l < line.size(); ++l){
for(unsigned i = 0; i < seperator.size(); ++i){
if(line[l+i]==seperator[i]){
if(i==seperator.size()-1){
values->push_back(tString);
tString = "";
++counter;
}else continue;
}else{
tString.push_back(line[l]);
break;
}
}
}
return counter;
}
现在我们将自己编写一个简单的 main 来读取文件,使用 split 将其分解,然后根据其在文件中的位置输出数据。
int main(){
std::vector<std::vector<std::string> > lines;
std::string tString = "";
std::vector<std::string> tVector;
std::ifstream fileToLoad;
fileToLoad.open(FILE_NAME);
if(fileToLoad.is_open()){
while(std::getline(fileToLoad,tString)){
split(tString, " ", &tVector);
lines.push_back(tVector);
tVector.clear();
}
//Now print our output.
for(unsigned i1 = 0; i1 < lines.size(); ++i1){
for(unsigned i2 = 0; i2 < lines[i1].size(); ++i2){
std::cout<<"["<<i1<<","<<i2<<"] = "<<lines[i1][i2]<<std::endl;
}
}
}else{
std::cerr<<"FAILED TO OPEN FILE: "<<FILE_NAME<<std::endl;
return 1;
}
return 0;
}
我使用的输入文件有数据:
450 105 10 10.5 -10.56001 23
10 478 1290 384 1289 3489234 1 2 3 4 5
1 2 3 4 5 6.1 19 -1.5
并且输出给出:
[0,0] = 450
[0,1] = 105
[0,2] = 10
[0,3] = 10.5
[0,4] = -10.56001
[1,0] = 10
[1,1] = 478
[1,2] = 1290
[1,3] = 384
[1,4] = 1289
[1,5] = 3489234
[1,6] = 1
[1,7] = 2
[1,8] = 3
[1,9] = 4
[2,0] = 1
[2,1] = 2
[2,2] = 3
[2,3] = 4
[2,4] = 5
[2,5] = 6.1
[2,6] = 19
现在您需要做的就是使用您最喜欢的解析算法将每个字符串更改为双精度字符串。 (strtod、atof 等)根据优化的重要性,您可能还想根据您的用例从矢量修改容器。
我有一个简短的 tab/space 分隔文件(我可以相应地创建它),其结构为
[data00] <space> [data01] <space> [data02] <space> [data03] <newline>
[data10] <space> [data11] <space> [data12] <space> [data13] <newline>
...
第一列代表数字 ID。我创建这个文件是为了将它提供给另一个可执行文件,所以格式是固定的。输入后,可执行文件输出另一个具有类似结构的文件:
[data00] <space> [data01]<newline>
[data10] <space> [data11]<newline>
...
给定一个ID,我需要读取对应的[dataX1]
,对第一个文件中的[dataX3]
进行操作,反馈给可执行文件,进行迭代。
我想到了两种方法:
- 对两个文本文件进行操作 "as if" 它们是数组,因为它们的结构是固定的,但我不知道 function/syntax 要使用什么。这应该是一个小函数,它可以让我通过传递相关的数字 ID 来读取有趣的部分,隐藏所有讨厌的 I/O 代码,因为我可能需要在不同的上下文中重复这个操作很多
- 将第一个文件保存在数组中并通过向其提供流来欺骗可执行文件(这可能吗?可执行文件需要一个文件作为参数)。
我可以轻松地将文件读入数组并每次重新写入文件,但我想避免无用的读写操作,而我每次需要 read/write 只是一个单元格。我现在不知道如何做的是当我通过使用 getline
.
首先,我们将编写一个函数,根据给定的分隔符拆分输入的字符串。 (在这种情况下,我们将使用 space。)
int split(const std::string& line, const std::string& seperator, std::vector<std::string> * values){
std::string tString = "";
unsigned counter = 0;
for(unsigned l = 0; l < line.size(); ++l){
for(unsigned i = 0; i < seperator.size(); ++i){
if(line[l+i]==seperator[i]){
if(i==seperator.size()-1){
values->push_back(tString);
tString = "";
++counter;
}else continue;
}else{
tString.push_back(line[l]);
break;
}
}
}
return counter;
}
现在我们将自己编写一个简单的 main 来读取文件,使用 split 将其分解,然后根据其在文件中的位置输出数据。
int main(){
std::vector<std::vector<std::string> > lines;
std::string tString = "";
std::vector<std::string> tVector;
std::ifstream fileToLoad;
fileToLoad.open(FILE_NAME);
if(fileToLoad.is_open()){
while(std::getline(fileToLoad,tString)){
split(tString, " ", &tVector);
lines.push_back(tVector);
tVector.clear();
}
//Now print our output.
for(unsigned i1 = 0; i1 < lines.size(); ++i1){
for(unsigned i2 = 0; i2 < lines[i1].size(); ++i2){
std::cout<<"["<<i1<<","<<i2<<"] = "<<lines[i1][i2]<<std::endl;
}
}
}else{
std::cerr<<"FAILED TO OPEN FILE: "<<FILE_NAME<<std::endl;
return 1;
}
return 0;
}
我使用的输入文件有数据:
450 105 10 10.5 -10.56001 23
10 478 1290 384 1289 3489234 1 2 3 4 5
1 2 3 4 5 6.1 19 -1.5
并且输出给出:
[0,0] = 450
[0,1] = 105
[0,2] = 10
[0,3] = 10.5
[0,4] = -10.56001
[1,0] = 10
[1,1] = 478
[1,2] = 1290
[1,3] = 384
[1,4] = 1289
[1,5] = 3489234
[1,6] = 1
[1,7] = 2
[1,8] = 3
[1,9] = 4
[2,0] = 1
[2,1] = 2
[2,2] = 3
[2,3] = 4
[2,4] = 5
[2,5] = 6.1
[2,6] = 19
现在您需要做的就是使用您最喜欢的解析算法将每个字符串更改为双精度字符串。 (strtod、atof 等)根据优化的重要性,您可能还想根据您的用例从矢量修改容器。