0

「input.txt」というファイルから入力を取得し、「output.txt」というファイルに出力を書き込むシーザー シフト暗号を実行するコードを作成しました。技術的には問題なく動作します。出力はほぼ完全に出力されますが、実行すると、出力ファイルを閉じる行Debug Assertion Failedに関するメッセージが表示されます。Line 56エラーにも次のように表示されます: Expression: (unsigned)(c+1) <= 256. これが私のコードです:

void cipher(char input[], int key);

int main()
{

    int i, key=0;
    char c, input[MAX];
    FILE *file1;
    file1 = fopen("input.txt","r");

    printf("Enter the key: ");
    scanf("%d", &key);
    getchar();

    for(i=0;(c=getc(file1))!=EOF && i<MAX;i++)
        input[i]=c;
    fclose(file1);
    cipher(input, key);
    return 0;
}

void cipher(char input[], int key)
{
    int length = strlen(input)-1;
    int i;
    char c;
    FILE *file2;
    file2 = fopen("output.txt","w");
    for (i=0;i<length;i++)
    {
        if (isalpha(input[i]))
        {
            c = (toupper(input[i]) - 'A'+key) % 26 + 'A';
            fprintf(file2, "%c", c);
        }
        else if (input[i]==' ')
            fprintf(file2, "\n");
    }

    fclose(file2);
}

ああ、それほど差し迫った問題ではありませんが、コードが入力を吐き出すときに、入力が「input text\n here」のように行を変更した場合、「text」と「here」の暗号化を行うと、それらがまとめられます想定されているように、それらを別々の行に配置する代わりに。誰かがその理由を知っていて、私を助けてくれれば幸いですが、主なことはそのエラーです。

4

2 に答える 2

0

ここには 2 つの問題があります。

char c, /* ... */;
for(i=0;(c=getc(file1))!=EOF && i<MAX;i++)
    input[i]=c;

これは間違っています。getcは an を返すintので、 c も an でなければなりませんint。その理由は、 には 2 種類の戻り値があるためですgetc

  1. unsigned charとして表すことができる正の値。
  2. エラーを示す負の値。

に直接変換するとchar、エラーをチェックする方法がありません。char署名されている場合と署名されていない場合があります。符号なしの場合、(c=getc(file1))は正の数になり、 と等しい可能性はありませんEOF。したがって、EOFが発生してもループは終了しません。が署名されている場合、ループの終了が早すぎたり、一部のマシンでセグメンテーション違反charが発生したりするなど、他の奇妙な方法でプログラムが誤動作する可能性があります。

これはすべての標準 C 関数に当てはまります。変換する前に必ず戻り値を確認してください! それが含まれscanfます。

<ctype.h>isalphatoupper関数を取得する場所です。

7.4 文字の扱い

1 ヘッダーは、文字の分類とマッピングに役立ついくつかの関数を宣言ます 。引数が他の値を持つ場合、動作は未定義です。

に負の値を渡す可能性があるため、未定義の動作を呼び出しているように思えますisupper

于 2013-04-24T05:49:23.187 に答える
0

MSVC を使用している場合は、isalpha に渡されたパラメーターが範囲内にあるかどうかをデバッグ CRT がチェックすることに注意してくださいEOF( MSDN0..0xffを参照)。あなたのコードでは、配列で呼び出しています。が必要なので、許容範囲外の値で呼び出すことになる可能性があります。に電話を変更する必要があります。isalpha(input[i])inputcharisalphaintisalphaisalpha((unsigned char)input[i])

それに応じて呼び出しも変更しますtoupper

そして、undefined behaviourすでに述べたように、結果を変数に格納し、それと比較してから a に変換して格納する必要getcintありEOFますchar。に変換した後は、もうchar比較できませEOFん (EOFintとして表現できない値ですchar)。

于 2013-04-24T09:53:26.320 に答える