0

セグメンテーション違反は、触れてはならないメモリを使用しようとしていることを意味することを理解していますが、コードのどこから来ているのかわかりません。vigenere の暗号を使用してプレーン テキストを暗号化する課題用のプログラムを作成しました。正常にコンパイルされますが、コマンド ライン引数を指定して実行すると、セグメンテーション エラーが発生します。

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main(int argc, string argv[])
{
// check to make sure the user entered a key
    if(argc != 2)
    {
        printf("You need to enter a key, and only one. Please enter an alphabetical key. \nSyntax: ./vigenere key \n");
        exit (1);
    }

// check to make sure the key is alphabetical
    string k = argv[1];
    if(isalpha(k) == false)
    {
         printf("Pleas enter an alphabetical key.\n");
         exit (2);
    }   
// Get a string of plaintext
    printf("Please enter your secret messege.\n");
    string p = GetString();
// Encipher
    int lk = strlen(k);
    int lp = strlen(p);
    for(int i = 0, j = 0; i < lp; i++, j++)
    {
        if(isupper(k[j]))
        {
            tolower(k[j]);
        }
        if(j > lk)
        {
            j = 0;
        }
        if(isalpha(p[i]))
        {
            if (islower(p[i]))
            {
                printf("%c", ((((p[i] - 97) + (k[j] - 97)) %26) +97));
            }
            else
            {
                printf("%c", ((((p[i] - 65) + (k[j] - 97)) %26) +65));
            }
        }
        else
        {
            printf("%c", p[i]);
        }
    }
    printf("\n");
    return 0;
}
4

3 に答える 3

3

このコードは疑わしいようです:

if(isupper(k[j]))
    {
        tolower(k[j]);
    }
    if(j > lk)
    {
        j = 0;
    }

k[j] を使用しますが、その後のチェックで、j が lk よりも大きい可能性があることが示唆されます。したがって、k[j] は範囲外になる可能性があります。

于 2014-06-05T23:34:08.917 に答える
1

あなたの行if(isalpha(k) == false)は文字列全体をチェックしていません。isalpha() は整数の引数のみを取ります。

文字列全体を調べて、すべての文字に対して isalpha() を呼び出す必要があります。

for( size_t i = 0 ; i < strlen( k ) ; i++ )
{
    if(isalpha(k[i]) == false)
    {
        printf("Pleas enter an alphabetical key.\n");
        exit (2);
    }
} 
于 2014-06-05T23:35:29.243 に答える
0

このコードのトラブルシューティングを行うには、cs50.h の内容、データ型 "string" の定義方法、および GetString() とは何かを知る必要があります。次の行でセグメンテーション違反が発生する可能性があります。p がポインタで、GetString() によって返される「文字列」を格納するためのメモリが割り当てられていない場合。

cs50.h が含まれていない場合、"string" は文字配列として再定義され、GetString() は fgets() に置き換えられます (他のいくつかの小さな変更と共に)、コードは機能します。以下を参照して、クラスの必要に応じて変更してください。

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

int main(int argc, char *argv[])
{
    // check to make sure the user entered a key
    if (argc != 2)
    {
        printf("You need to enter a key, and only one. Please enter an alphabetical key. \nSyntax: ./vigenere key \n");
        exit (1);
    }

    // check to make sure the key is alphabetical
    //string k = argv[1];
    char *k = argv[1];
    char *sp;
    for (sp = argv[1]; *sp != '\0'; sp++) {
        if(!isalpha(*sp))
        {
            printf("Pleas enter an alphabetical key.\n");
            exit (2);
        }   
    }

    // Get a string of plaintext
    printf("Please enter your secret message.\n");
    //string p = GetString();
    char p[256];
    fgets(p, 256, stdin);

    // Encipher
    int lk = strlen(k);
    int lp = strlen(p);
    int i;
    int j;
    for(i = 0, j = 0; i < lp; i++, j++)
    {
        if(isupper(k[j]))
        {
            k[j] = tolower(k[j]);
        }
        if(j > lk)
        {
            j = 0;
        }
        if(isalpha(p[i]))
        {
            if (islower(p[i]))
            {
                printf("%c", ((((p[i] - 97) + (k[j] - 97)) %26) +97));
            }
            else
            {
                printf("%c", ((((p[i] - 65) + (k[j] - 97)) %26) +65));
            }
        }
        else
        {
            printf("%c", p[i]);
        }
    }
    printf("\n");
    return 0;
}
于 2014-06-06T02:34:54.213 に答える