我正在尝试在C ++中重新实现dos2unix
和unix2dos
。这是我的dos2unix
:
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
// save as d2u.cpp, compile '$ g++ d2u.cpp -o d2u'
// execute '$ ./d2u sample.txt'
int main(int argc, char** argv) {
string fn ="";
char c;
if (argc == 2) { fn = argv[1]; }
ifstream is(fn.c_str());
ofstream os("temp.txt");
while (is >> c) {
switch(c) {
// 0x0D = '\r', 0x0A = '\n'
case 0x0D: break;
case 0x0A: os << (char)0x0A; break;
default: os << c; break;
}
}
is.close(); os.close();
string command = "mv temp.txt " + fn;
system(command.c_str());
return EXIT_SUCCESS;
}
由于DOS文本文件的换行符以\r\n
结尾,因此我想忽略\r
,而仅将\n
输出到新文件。使用文本文件对其进行测试并比较十六进制转储,但是除删除所有\r
和\n
之外,其他操作均未完成:
74 65 73 74 0d 0a 74 65 73 74 32 0d 0a 74 65 73 74 33
t e s t \r \n t e s t 2 \r \n t e s t 3
74 65 73 74 74 65 73 74 32 74 65 73 74 33
t e s t t e s t 2 t e s t 3
74 65 73 74 0a 74 65 73 74 32 0a 74 65 73 74 33
t e s t \n t e s t 2 \n t e s t 3
为什么会这样?我的unix2dos
实现得到类似的行为。
为了避免>>
消除输入中的空格,最简单的更改就是使用is.get(c)
而不是is >> c
。 std::basic_istream::get表现为Unformatted输入函数,将逐字符读取文件中的所有内容。 std::basic_iostream运算符>>
提供Formatted输入,可消除空格。
更改为istream。get()
提供了您描述的行为,
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char** argv) {
std::string fn {};
char c;
if (argc < 2) { /* validate filename provided */
std::cerr << "error: filename required.\n";
return 1;
}
fn = argv[1];
std::ifstream is (fn.c_str());
std::ofstream os ("temp.txt");
while (is.get(c))
if (c != '\r')
os.put(c);
string command = "mv temp.txt " + fn;
system(command.c_str());
}
示例输入文件
$ cat dat/fleas2line.txt
my dog has fleas
my cat has none
示例使用/输出文件
您可以看到'\n'
被保留在您的输入中。
$ hexdump -Cv temp.txt
00000000 6d 79 20 64 6f 67 20 68 61 73 20 66 6c 65 61 73 |my dog has fleas|
00000010 0a 6d 79 20 63 61 74 20 68 61 73 20 6e 6f 6e 65 |.my cat has none|
00000020 0a |.|
temp.txt
$ cat temp.txt
my dog has fleas
my cat has none
[最后,请避免在代码中使用0XD
和0XA
,而应使用字符本身,例如'\r'
和'\n'
。它使代码更具可读性。仔细检查一下,如果还有其他问题,请告诉我。