我目前正致力于将文件解析为程序内存。
要解析的文件如下所示:
file info
second line of file info
date
# col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 col14
firstSetOfElements
4
2 1 1 0 3 1 2 3 0 -49.4377 0 0 -26.9356 -24.5221
3 2 1 0 3 2 4 3 13.7527 -43.2619 0 0 -19.3462 -28.0525
4 3 1 0 3 4 1 3 14.2459 43.5163 0 0 33.3506 15.2988
5 4 1 0 3 2 1 4 49.4377 0 0 0 25.0818 38.3082
# col1 col2 col3 col4 col5 col6
secondSetOfElements
1
1 4 3 4 1 2
我想做什么:
file.open(FILENAME, ios::in); // Open file
if (file.is_open())
{
// Get the line number where "firstSetOfElements" is located. Store the line number.
// Go to the line after that line, and store the integer listed there as a variable (`int noFirstElems`).
// (this is the number of rows I will be parsing into the first array).
// start parsing at the first line of the array (the line under the previous)
while (getline(file, firstLineOfFirstSetToParse)) //starting at the first row of data array elements, begin parsing into text file (this I've got handled).
{
//add a row vector until you get to a blank line (which will be after 4 rows of data).
}
为" firstSetOfElements"执行此操作后数组,我将做同样的事情来解析" secondSetOfElements"数据如上所示。
我已经很好地解析了数据,但是没有找到我可以理解的资源来设置我要解析的行的开始/结束点。
提前致谢!
答案 0 :(得分:1)
基于您所描述的方式的问题很容易解决:逐行读取,扫描名为&#34的令牌; SetOfElements"并将下一行视为2D数组的大小,然后读取size
行数并将它们存储到数组中。
但是,您的文件布局令人困惑:您的注释行(以#开头)表示将有8列,但后续行包含14列。你的程序是否应该忽略最后6列?此外,您的元素似乎是整数和浮点数的混合,除非第1列到第8列也是不具有小数部分的浮点数。
实际上,如果数据类型是混合的,并且列1-8必须作为整数读取而剩余的作为浮点数,那么您的解析器代码将变得复杂,否则它应该是简单的getline... scan line... continue
一种算法。
另外,您的设置分隔符是否会更改?第一组由" firstSetOfElements"并且第二组的id是" secondSetOfElements",如果他们只是" SetOfElements"会更容易,否则你会在读取每个新的元素集之前构造分隔符字符串
答案 1 :(得分:1)
这可能会给你一些想法:
std::string line;
int line_num = 0;
for (int i = 0; i < 3; ++i)
assert(getline(input, line))); // ignore 3 lines
while (input >> set_name)
{
if (set_name == '#') { input.ignore('\n'); continue; }
std::vector<std::vector<float>>>& set = sets[set_name];
if (input >> rows)
for (int i = 0; i < rows && getline(input, line); ++i)
{
std::istringstream iss(line);
set.push_back(std::vector<float>());
while (iss >> num) set.back().push_back(num);
}
}
答案 2 :(得分:1)
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
string trimmed(string& input)
{
size_t firstNonWSIdx = input.find_first_not_of(" ");
size_t lastNonWSIdx = input.find_last_not_of(" ");
firstNonWSIdx = (firstNonWSIdx == string::npos ? 0 : firstNonWSIdx);
return input.substr(firstNonWSIdx, lastNonWSIdx);
}
void resetStrStream(istringstream& sstr, string const& newInput)
{
sstr.clear();
sstr.str(newInput);
}
void readFile(char const* fileName, vector<vector<float> >& data)
{
ifstream infile(fileName);
string input;
istringstream iss;
while(infile)
{
getline(infile, input);
string token = trimmed(input);
if (token.compare("setOfElements") == 0)
{
getline(infile, input);
resetStrStream(iss, trimmed(input));
int arraySize;
iss >> arraySize;
vector<float> values;
int i = 0;
while(i++ < arraySize)
{
getline(infile, input);
resetStrStream(iss, trimmed(input));
float val;
while (iss >> val)
{
values.push_back(val);
}
}
data.push_back(values);
}
}
}
void testData(vector<vector<float> >& data)
{
for (int i = 0; i < data.size(); i++)
{
for (int j = 0; j < data[i].size(); j++)
{
cout << data[i][j] << " ";
}
cout << endl;
}
}
int main()
{
vector< vector<float> > data;
readFile("textfile.txt", data);
testData(data);
return 0;
}