我正在使用一个简单的C++程序转换大型图形文件。基本上我主要想切换文件中使用的分隔符。这些图形文件包含极长的线条。我的转换适用于小文件,但我在大文件的输出文件中丢失了边缘。所以我检查了读取的代码部分实际返回的内容,似乎错误已经存在。使用以下方法,我没有以curLineMetis
或ssMetis
从图形中接收到完整的行(我的猜测是某处溢出,我丢失了行的最后一部分,对于分配的内存来说太大了)
using namespace std;
void exampleFunc(const char* inputfileMetis) {
ifstream metisFile;
metisFile.open(inputfileMetis, ios::in);
if(!metisFile.is_open()) {
cout << "Could not open input file";
return;
}
long nMet = 0;
long mMet = 0;
string curLineMetis;
// skip first line
getline(metisFile, curLineMetis);
while(getline(metisFile, curLineMetis)) {
nMet++;
long targetMetis;
stringstream ssMetis(curLineMetis);
while(ssMetis >> targetMetis) {
mMet++;
}
}
}
我在谷歌上检查了一下,它说 std::string 管理自己的内存并且不会溢出?我也尝试过没有字符串流,只是在之前对字符串中的字符使用迭代器,同样的事情发生了。如果这有所作为,我正在使用 c++11。(误差表现为mMet
与图形文件本身中规定的边数不同,而nMet
的顶点数相同,并且对于较小的图,边数也是正确的)
我不太确定你的代码出了什么问题。标准库函数和类型应该能够处理长行。但是,若要减少内存使用量并变通解决此问题,您可能希望一次处理一行的一部分。由于文件格式似乎很有趣,我编写了这个程序来将图形读取到vector<vector<int>>
中。它从该表示形式复制图形文件,并生成与输入相同的文件。也许这里的东西对你有用。祝你好运。
#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
int
main(int argc, char* argv[])
{
size_t const buf_size = 40; // big enough for a 64bit integer and then some
char buf[buf_size];
assert(argc >= 2);
std::ifstream is (argv[1]);
assert(is);
std::vector<std::vector<int>> graph;
std::vector<int> line;
std::string header;
std::getline(is, header);
{ std::istringstream is_header (header);
size_t n;
is_header >> n;
graph.reserve(n);
}
char delim;
for (;;) {
is.get(buf, buf_size, ' ');
if (!is) break;
is.get(delim);
line.push_back(std::atoi(buf));
while (is.peek() == 'n') {
graph.emplace_back(std::move(line));
(void) is.get();
}
}
std::cout << graph.size() << 'n';
size_t max_row = graph[0].size();
size_t row_sum = graph[0].size();
for (size_t i = 1, I = graph.size(); i < I; ++i) {
max_row = std::max(max_row, graph[i].size());
row_sum += graph[i].size();
}
std::cout << max_row << 'n';
std::cout << row_sum << 'n';
std::ofstream os ("dup.graph");
os << header << 'n';
for (size_t i = 0, I = graph.size(); i < I; ++i) {
for (size_t j = 0, J = graph[i].size(); j < J; ++j)
os << graph[i][j] << ' ';
os << 'n';
}
return 0;
}