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)それらは1つの改行でもあります!

行番号と列番号を処理する関数は次のとおりです。

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

_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 に答える
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;
    }
}

aが処理される時点で、の文字がキャリッジリターン( )\nであるかどうかをチェックします。その場合、行番号は増加しません。\r

また、前の文字をチェックする前に、実際に前の文字(and _position > 0)があるかどうかをテストします。

私が int revue 達成したかったことは、私がそれを達成しようとした方法では不可能であることに気付いたので、私は議論を削除しました。ソースを逆方向に移動できるようにしたかったのですが、前の行から列番号を取得できません。

于 2012-06-11T15:51:47.017 に答える