1

この小さな問題があり、解決できません。問題は、ユーザーに挿入を求めること
で、関数に 4 つの文字列すべてをロードしようとしているということです。LOADすべて問題ないようで、コンパイラ エラーは発生しません。しかし、空のままeafです。、、に置き換えても、多くの方法を試しましたが、何も変わりません。scanfgetsgets_sfgets

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

void LOAD(char eaf[], char initials[], char finals[], char symbols[]);
int COMPARE(char s[], char eaf[]);

int main()
{
    char eaf[10],initials[1],finals[10],symbols[5];
    LOAD(eaf, initials, finals, symbols);
    return 0;
}


void LOAD(char eaf[], char initials[], char finals[], char symbols[])
{
    printf("Insert states of the optimized AFD\n");
    scanf( " %s", eaf);

    printf("Insert AFD initial state\n");
    do
    {
        scanf( " %s", initials);
    } while (COMPARE(initials, eaf));

    printf("Insert final state(s)\n");
    do
    {
        scanf( " %s",finals);
    } while (COMPARE(finals, eaf));

    printf("Insert the language symbols\n");
    scanf( " %s",symbols);
}

int COMPARE(char s[], char eaf[])
{
    int i;
    char *ptr;
    for(i; i < strlen(s); i++){
            printf("%d\n", i);
        while(ptr==NULL){
            ptr = strchr(eaf, *s);
        }
    }
    if (ptr == NULL) return 1;
    else return 0;
}

私は何を間違っていますか?これはより大きなプログラムのほんの一部ですが、残りeafは空であるため役に立ちません。問題は の使用にあると思いましたが、前述しscanfたように他の機能も同様に機能しませんでした。誰でも私を助けてくれることを願っています。ありがとう

編集:チェックしましたstrlen(eaf)

4

2 に答える 2

1

入力に「scanf」を使用するのは危険であり、その危険に直面しています。イニシャルを文字列として読み取るように要求すると、「eaf」の内容を上書きできるようになり、終端の 0 が追加されます。

最終的に、配列の次元が間違っているため、文字列は空になります。"initials" に配列サイズ 1 を指定したため、末尾の '\0' C 文字列ターミネータにスペースがありません。

ideoneでこのコードのライブ デモを参照してください。

#include <stdio.h>

void report(char* eaf, char* initials, char* foo)
{
    printf("eaf = %p, initials = %p, foo = %p\n", eaf, initials, foo);;
    printf("*eaf = %d, *initials = %d, *foo = %d\n", eaf[0], initials[0], foo[0]);
}

void load(char eaf[], char initials[], char foo[])
{
    printf("load\n");
    report(eaf, initials, foo);

    printf("Enter EAF\n");
    scanf(" %s", eaf);
    report(eaf, initials, foo);

    printf("Enter initial state\n");
    scanf(" %s", initials);
    report(eaf, initials, foo);
}

int main(int argc, const char* argv[])
{
    char eaf[10], initials[1], foo[10];
    report(eaf, initials, foo);
    load(eaf, initials, foo);
    report(eaf, initials, foo);

    return 0;
}

デバッガーでこれを見て、「eaf」と「initials」の値を見て、進行中に何が起こったかを確認する必要があります。

このプログラムは C で書かなければなりませんか? perl や python などのスクリプト言語を使用する方が簡単なようです。

これは、問題の解決を開始するための実用的な C メソッドです。実際に問題を修正したわけではありませんが、見やすくなります。

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

void report(char* eaf, char* initials, char* foo)
{
    printf("eaf = %p, initials = %p, foo = %p\n", eaf, initials, foo);;
    printf("*eaf = %d, *initials = %d, *foo = %d\n", eaf[0], initials[0], foo[0]);
}

void load(const char* label, const char* into, size_t intoSize)
{
    assert(intoSize > 1); // can't store a string in 1 character.
    printf("%s\n", label);

    char input[1024] = "";
    fgets(input, sizeof(input), stdin);

    size_t len = strlen(input);
    // strip trailing \n off.
    if (len > 0 && input[len - 1] == '\n') {
        input[--len] = 0;
    }

    // abort on empty input
    if (len <= 0) {
        fprintf(stderr, "Invalid input - terminated.\n");
        exit(1);
    }

    if (len >= intoSize) {
        fprintf(stderr, "Invalid input - length was %u, limit is %u\n", len, intoSize - 1);
        exit(2);
    }

    strncpy(into, input, intoSize);
}

int main(int argc, const char* argv[])
{
    char eaf[10], initials[1], foo[10];
    report(eaf, initials, foo);

    load("Insert states of the optimized AFD", eaf, sizeof(eaf));
    report(eaf, initials, foo);

    load("Insert initial AFD state", initials, sizeof(initials));
    report(eaf, initials, foo);

    printf("eaf = %s\ninitials = %s\n", eaf, initials);

    return 0;
}

ここで ideone のライブ デモを参照してください。

于 2013-07-11T20:40:28.353 に答える
0

フォーマット文字列がscanf原因である可能性が最も高いです。の前に余分なスペースがあり%sます。

変化する:

scanf( " %s", eaf);

scanf( "%s", eaf);

すべてのあなたscanfのために。

「 blahblahblah 」ではなく「 blahblahblah」(先頭のスペースに注意)eaf形式の文字列を探しているため、入力を入れていません

編集

上記を無視して、

whitespace: 空白文字は、ゼロ個以上の空白文字のスキャンをトリガーします。空白文字の数とタイプは、どちらの方向でも一致する必要はありません。

また、関数で初期化する必要がありiますCOMPARE(コンパイラから怒っている警告が表示されない方法がわかりません)。コードを変更せずに実行しstrlen(eaf)、正しいカウントを返しました (の直後scanf)。

于 2013-07-11T20:09:21.823 に答える