我是C ++的初学者,所以我希望你能忍受我。
尝试读取一个文本格式的文件,每个文件都有这样的行(前几行,称为标题行):
@HD VN:1.5 SO:queryname
或者像这样
read.1 4 * 0 0 * * 0 0 CAACCNNTACCACAGCCCGANGCATTAACAACTTAANNNCNNNTNNANNNNNNNNNNNNTTGAAAAAAAAAAAAAAAAAA A<.AA##F..<F)<)FF))<#A<7<F.)FA.FAA.)###.###F##)############)FF)A<..A..7A....<F.A XC:Z:CAACCNNTACCA RG:Z:A XQ:i:2
两者都是制表符分隔。
文件非常大,因此是二进制格式。 我想知道是否可以从每行的二进制格式文件中读取,在该行上进行一些处理,然后将其写入二进制格式的输出文件。
我从这段代码开始:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
string input_file = argv[1];
string output_file = argv[2];
string line;
ifstream istream;
istream.open(input_file.c_str(),ios::binary|ios::in);
ofstream ostream;
ostream.open(output_file.c_str(),ios::binary|ios::out);
while(getline(istream,line,'\n')){
if(line.empty()) continue;
//process line assuming it is read as a string
ostream<<line<<endl;
}
istream.close();
ostream.close();
}
但是,在{I}尝试将Segmentation fault (core dumped)
解析为line
string
的部分,它与vector
崩溃。
有没有办法读取二进制格式并按行拆分,在每条这样的行上进行字符串处理,然后将它们写入二进制输出?
顺便说一下,我在Linux上运行它。
答案 0 :(得分:8)
是否可以逐行读取二进制文件?
原则上,每个文件都是二进制文件,因为这就是计算机的工作方式。现在,说“我试图逐行阅读”显然意味着你将它视为文本文件 - “行”是一个文本概念。
文件非常大,因此是二进制格式。
这是一流的废话。大小不会改变文件的格式。
如何将每一行作为字符串?
ostream<<line<<endl;
是否可以将字符串写入二进制文件?
是和否:如果您的文件是而不是文本文件,为什么这些'\n'
字符的位置很重要?对于非文本文件,这些只是普通字节,如'a'
或\0x00
或0xFF
。所以基本上,你正在看并尝试在那里发现字母。
但是,通过您对我们正在讨论的文件的说明,它们实际上是仅包含文本的文件。
所以你的问题似乎在于,一行可能会超过std::string
中可用的存储空间。这是一种罕见的情况 - 但它似乎可能发生在遗传字符串上。好。
熟悉C ++所具有的非文本文件I / O.基本上,有ifstream.read()
,您应该使用它来获取(有限的)字节数,进行处理,写入输出,重复。请注意输入中的换行符,如果您已阅读过,则“倒回”您的文件(fseek
)。
另外,我真的很想知道你的线要走多长时间才能打破std::string
。我想你可能正在运行一些非常有限的操作系统(32位?)或计算机(非常少的RAM +交换?)。
答案 1 :(得分:2)
如果您的文件结构为行,并且每行以\n
终止,则 是文本文件。每个文件都是二进制文件,文本文件只是一种特殊的二进制文件。
因此,鉴于此,您展示的代码可能适用于任何大小的文件。
你应该删除ios:binary
,但我不认为在这种情况下会有任何不同。
但是,如果您在“处理”文件的某一行时遇到崩溃,那么这就是最有可能出现错误的地方 - 在您尚未披露的代码中 - 但是!
答案 2 :(得分:1)
看起来你的文件有一些比你预期的其他行结尾。它可能有一个\r
,而您希望它有\n
。如果是这种情况,那么std::getline
会尝试将整个30GB文件读入line
std :: string。
我建议您查看文件中的结尾,以便验证上述内容。如果是这种情况,那么您可以使用此SO中的行读取功能:Getting std :: ifstream to handle LF, CR, and CRLF?即使它们的结尾与您的平台不兼容(或者更确切地说是您不期望的结尾),也应该读取行。
另外,使用非二进制文件模式应该没问题。您显示的示例文件行对我来说看起来不是二进制文件。