连接两个文件时如何避免冗余尾随换行符?

How do I avoid a redundant trailing newline when concatenating two files?

本文关键字:冗余 何避免 换行符 文件 两个 连接      更新时间:2023-10-16

我想将两个文件合并为一个文件,当我在合并文件的末尾执行此操作时,有一个额外的空行,如何删除它?

文件1包含:

1  2  3

和文件2包含:

4  5  6

合并的文件就像

1  2  3
4  5  6
<------cursor is here

这是我的代码:

ifstream read1("1.txt");
ifstream read2("2.txt");
ofstream write ("3.txt");
string line;
string line2;
while ( getline ( read1, line, 'n' ) )
{
 if (!line.empty())
  write << line << endl;
}
while ( getline ( read2, line2, 'n' ) )
{
 if (!line2.empty())
  write << line2 << endl;
}
read1.close();
read2.close();
write.close();

使用 streambuf 重载进行operator<<我们可以做到:

#include <fstream>
int main()
{
    std::ifstream read1("1.txt");
    std::ifstream read2("2.txt");
    std::ofstream write("3.txt");
    write << read1.rdbuf() << 'n' << read2.rdbuf();
}

在第二个同时读取第一行之前,将其写入文件,然后 像以前一样使用 while,但先输入新行。 像这样:

getline(read2 , line2, 'n');
if (!line2.empty()) 
   write << line2;
while ( getline ( read2, line2, 'n' ) )
{
 if (!line2.empty())
  write << endl <<line2;
}

这不完全是你要求的,但它应该可以解决问题。

<

如果您不想添加换行符,只需将代码编写为: ifstream read1("1.txt"(; ifstream read2("2.txt"(;

ofstream write ("3.txt");
string line;
string line2;
while ( getline ( read1, line, 'n' ) )
{
 if (!line.empty())
  write << line;
}
while ( getline ( read2, line2, 'n' ) )
{
 if (!line2.empty())
  write << line2;
}
read1.close();
read2.close();
write.close();

如果您希望在事实中除最后一个文件的最后一行之外的每一行之后写一个换行符,而不是将事物缓冲成字符串并将其写入文件......也许不是最有效的选择,但足够好:

ifstream read1("1.txt");
ifstream read2("2.txt");
ofstream write ("3.txt");
string line;
string line2;
string buffer
while ( getline ( read1, line, 'n' ) )
{
 if (!line.empty())
  buffer += line;
  buffer += "n";
}
while ( getline ( read2, line2, 'n' ) )
{
 if (!line2.empty())
        buffer += line2;
        buffer += "n";
}
//Remove the last char from buffer (the 'n' bothering you)
buffer.substr(0, myString.size()-1)
write << buffer;
read1.close();
read2.close();
write.close();

Marek Vitek的回答其实比我的好:

ofstream write ("3.txt");
string line;
string line2;
while ( getline ( read1, line, 'n' ) )
{
 if (!line.empty())
  write << line << endl;
}
while ( getline ( read2, line2, 'n' ) )
{
 if (!line2.empty()) {
  write << line2 
 } 
 if(!line2.empty() && !read2.eof() {
  write << line2 << endl;
 } 
}
read1.close();
read2.close();
write.close();

原始副本怎么样:

std::ifstream read1{path1};
read1.unsetf(std::ios_base::skipws);
std::ifstream read2{path2};
read2.unsetf(std::ios_base::skipws);
std::ofstream write{path3};
std::copy(std::istream_iterator<char>(read1),
          std::istream_iterator<char>(),
          std::ostream_iterator<char> (write));
write << 'n'; // extra EOL between file
std::copy(std::istream_iterator<char>(read2),
          std::istream_iterator<char>(),
          std::ostream_iterator<char> (write));

测试输入文件的末尾,不要在末尾放置额外的换行符。
改变

write << line2 << endl;

{
    write << line2;
    if (!read2.eof()) {write << "n";}
}

编辑:我添加了大括号来补偿您的单行IF。请尽量在代码中避免它。看看乔治是如何轻易落入这个陷阱的。

另一个简短的解决方案(尽管我不知道合并结果中的最后一个换行符应该有什么问题(:

ifstream read1("1.txt");
ifstream read2("2.txt");
ofstream write ("3.txt");
string line;
string line2;
do {
    if (!line.empty())
       write << line << 'n';
} while( getline ( read1, line, 'n' ) )
write.flush();
do {
    if(!line2.empty())
        write << line2;
} while( getline ( read2, line2, 'n' ) && write << `n`);
read1.close();
read2.close();
write.close();

合并两个具有额外换行符的文件

std::ifstream ifs_1( "file1" );
std::ifstream ifs_2( "file2" );
std::ofstream ofs( "file3" );
for( std::string line; std::getline( ifs_1, line ); ){
    if( line != "" ){
        ofs << line << 'n';
    }
}
for( std::string line; std::getline( ifs_2, line ); ){
    if( line != "" ){
        ofs << line << 'n';
    }
}
ifs_1.close();
ifs_2.close();
ofs.close();

测试:

cat file1
one
two
--> empty
--> empty

和文件 2:

cat file2:
three
four
--> empty
--> empty

输出:

cat file3
one
two
three
four