在 C++ 中重新实现 dos2unix 和 unix2dos; '\r' 和 '\n' 没有出现在 hexdump 中?
Reimplementing dos2unix and unix2dos in C++; '\r' and '\n' not appearing in hexdump?
我正在尝试用 C++ 重新实现 dos2unix
和 unix2dos
。这是我的 dos2unix
:
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
到新文件。然而,使用文本文件对其进行测试并比较 hexdumps 表明除了删除所有 \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 behaves as an Unformatted input function and will provide a character-by-character read of everything in the file. The std::basic_iostream operator >>
提供 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
示例Use/Output文件
您可以看到 '\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'
。它使代码更具可读性。检查一下,如果您还有其他问题,请告诉我。
我正在尝试用 C++ 重新实现 dos2unix
和 unix2dos
。这是我的 dos2unix
:
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
到新文件。然而,使用文本文件对其进行测试并比较 hexdumps 表明除了删除所有 \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 behaves as an Unformatted input function and will provide a character-by-character read of everything in the file. The std::basic_iostream operator >>
提供 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
示例Use/Output文件
您可以看到 '\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'
。它使代码更具可读性。检查一下,如果您还有其他问题,请告诉我。