我正在编写一个简单的包装类,用于逐个字符地扫描字符流。
Scanner scanner("Hi\r\nYou!");
const char* current = scanner.cchar();
while (*current != 0) {
printf("Char: %d, Column: %d, Line: %d\n", *current, scanner.column(), scanner.line());
current = scanner.read();
}
C:\Users\niklas\Desktop>g++ main.cpp -o main.exe
C:\Users\niklas\Desktop>main.exe
Char: 72, Column: 0, Line: 0
Char: 105, Column: 1, Line: 0
Char: 13, Column: 0, Line: 1
Char: 10, Column: 0, Line: 2
Char: 89, Column: 1, Line: 2
Char: 111, Column: 2, Line: 2
Char: 117, Column: 3, Line: 2
Char: 33, Column: 4, Line: 2
这个例子已经显示了我遇到的问题。可以将\r
解释为换行符,以及\n
。但是在一起(\r\ n
)它们也只是一个单个新行!
处理行号和列号的函数是:
void _processChar(int revue) {
char chr = _source[_position];
if (chr == '\r' or chr == '\n') {
_line += revue;
_column = 0;
}
else {
_column += revue;
}
}
当然,我可以看一下在当前位置后出现的字符但是:我不检查源上的NULL终止,因为我希望能够处理可能包含\0
个字符的字符流,而不会在此时终止。
如何以这种方式处理CRLF?
编辑1 :DOH!这似乎工作正常。这在任何情况下都是安全的,还是我在某个地方有问题?
void _processChar(int revue) {
char chr = _source[_position];
bool is_newline = (chr == '\r' or chr == '\n');
if (chr == '\n' and _position > 0) {
is_newline = (_source[_position - 1] != '\r');
}
if (is_newline) {
_line += revue;
_column = 0;
}
else {
_column += revue;
}
}
谢谢!
答案 0 :(得分:3)
大多数现代系统处理\n
作为当前目标平台的换行符,因此如果您只检查\n
,所有这些都会自动发生。
答案 1 :(得分:1)
您可能需要在流包装器中保持状态 - 一个无状态包装器,正如您已经注意到的那样,只是不能执行此操作,因为每个输出都可以(根据定义)依赖于先前的输出
答案 2 :(得分:0)
您的_processChar
似乎没有增加流读取位置。更改后,您可以实施完整的换行检查:
void _processChar(int revue) {
char chr = _source[_position];
if (chr != '\r' and chr != '\n') {
_column += revue;
return;
}
if (if chr == '\r' and _source[_position + 1] == '\n')
++_position;
_line += revue;
_column = 0;
}
答案 3 :(得分:0)
这对我来说似乎是合法的:
void _processChar() {
char chr = _source[_position];
// Treat CRLF as a single new-line
bool is_newline = (chr == '\r' or chr == '\n');
if (chr == '\n' and _position > 0) {
is_newline = (_source[_position - 1] != '\r');
}
if (is_newline) {
_line += 1;
_column = 0;
}
else {
_column += 1;
}
}
在处理\n
时,它会检查上一个字符是否为回车符(\r
)。如果是这样,则行号不增加。
此外,在检查前一个字符之前,它会测试是否实际上是前一个字符(and _position > 0
)。
我已经删除了 int revue
参数,因为我刚注意到我想要实现的目标是不可能的,因为我试图实现它。我希望能够在源代码中向后退,但我无法从上一行检索列号。