1

我正在编写一个简单的包装类,用于逐个字符地扫描字符流。

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;
    }
}

谢谢!

4

4 回答 4

3

大多数现代系统\n作为当前目标平台的换行符处理,因此如果您只检查\n.

于 2012-06-11T15:31:43.173 回答
1

您可能需要将状态保留在流包装器中——正如您所注意到的,无状态包装器根本无法做到这一点,因为每个输出都可以(根据定义)依赖于先前的输出。

于 2012-06-11T15:34:39.133 回答
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处理 a 时,它会检查前一个字符是否为回车符 ( \r)。如果是这样,则不增加行号。

此外,在检查前一个字符之前,它会测试是否确实存在前一个字符 ( and _position > 0)。

我已经删除了这个 int revue 论点,因为我只是注意到我想要实现的目标是不可能的,因为我试图实现它。我希望能够在源代码中倒退,但是我无法从上一行检索列号。

于 2012-06-11T15:51:47.017 回答
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;
}
于 2012-06-11T15:28:48.300 回答