1

したがって、私の問題は単純です。ファイル内の単語を分離し、それらの単語を解析し、それらの単語に対して特別な考えを作成する関数を作成したいのですが、トークンを分離しようとすると、strcat にエラーがあります。

コードを見てください:

#include <stdio.h>
#include <string>
#include <Windows.h>

using namespace std;

bool compile(FILE *fp)
{
    char c;
    char token[256];
    bool _return = false;

    while ((c = getc(fp)) != EOF)
    {
        if(isalpha(c))
        {
                    // The error is here
            strcat(token, (char*)c);
            printf("%c\n", c);
        }
        else
        {
            printf("----> %c\n", c);
        }
    }

    printf("%s\n", token);

    return _return;
}

int main()
{
    char *filename = "test.in";

    FILE *fp = fopen(filename, "rb");
    if(!fp)
    {
        return 1;
    }

    if(!compile(fp))
    {
        printf("ERROR...\n");
    }
    fclose(fp);
}

コードは正常にビルドされますが、デバッグすると、デバッガーは strcat.asm ファイルに移動します:(だから、私のエラーはどこですか、助けてくれてありがとう。(:

-0-0-0-0-0-0-0-0-0-> edit そして、strcat を次のように変更すると:

strcat(token, &c)

デバッガーから次のエラーが表示されます。

APP.exe の 0x20E801F2 で未処理の例外: 0xC0000005: アクセス違反 (パラメーター: 0x00000008)。

4

4 に答える 4

3

これは間違っています:

strcat(token, (char *) c);

変数cは文字列ではなく、1 文字のみです。へのキャスト(char *)は、コンパイラ エラーをマスクしているだけです。

文字列に文字を 1 つずつ追加する場合は、

std::size_t pos = 0;
char buf[256];

// ...

if (isalpha(c)) {
    assert(pos < sizeof(buf));
    buf[pos++] = c;
}

// ...

assert(pos < sizeof(buf));
buf[pos] = '\0';
printf("buf = %s\n", buf);

または、ご存知のように、簡単な方法で行います。

#include <string>

std::string s;

// ...

if (isalpha(c)) {
    s += c;
}

// ...

printf("buf = %s\n", s.c_str());

の内部をわざわざデバッグしないでくださいstrcat()。プログラムが 内でクラッシュする場合strcat()、それは呼び出し関数のエラーです。(通常、strcat()まったく呼び出すことさえエラーです。)

于 2012-11-20T01:45:42.203 に答える
2

strcatnull で終わる文字列が必要です。個々の文字へのポインターを渡して、それが正しく機能することを期待することはできません。

交換

strcat(token, (char*)c);

char tmp[2];
tmp[0] = c;
tmp[1] = '\0';
strcat(token, tmp);

それを機能させるために。

token[0]また、初期化されていないために未定義の動作を避けるために、ゼロに設定する必要があります。

于 2012-11-20T01:44:55.060 に答える
2

にキャストcするとchar *、文字に含まれていた値 ( 10016 進数など) がメモリ アドレス ( 0x100) に変換され、そのメモリ アドレスで文字列が検索されます。うまくいかないのも不思議ではありません!にポップする前に、文字を文字列に変換する必要がありますstrcat

于 2012-11-20T01:46:54.650 に答える
1

三つのこと:

  • バッファ内の 256 文字をオーバーフローするかどうかを確認しません
  • に変換char cする(char *) cと、 c がメモリアドレスであると言っています。実際には値です。おそらく必要なのは、キャラクターへの参照です。&c
  • 連結するものの最後に null ターミネータを追加する必要があります。
于 2012-11-20T01:46:24.720 に答える