簡體   English   中英

操作字符串時出現分段錯誤

[英]Segmentation Fault While Manipulating String

我正在嘗試創建一個凱撒密碼。 對於這個測試,我使用了 1 的鍵和“hello”的純文本。 這樣做時,我收到錯誤消息“分段錯誤(核心轉儲)”。 我知道這意味着我試圖訪問一個非法的內存位置,並且在調用“加密”函數時發生了這種情況,但這就是我所知道的。

描述我在調試時遇到的錯誤。

這是我的代碼。

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

bool isValidKey(string);
string encrypt(string, int);

string c;

int main(int argc, string argv[])
{
    if (argc != 2 || isValidKey(argv[1]) == 0)
    {
        printf("Useage: ./caesar key\n");
        return 0;
    }
    string p = get_string("plaintext: ");
    c = encrypt(p, atoi(argv[1]));
    printf("%s", c);
    return 0;
}

bool isValidKey(string key)
{
    for (int i = 0; i < strlen(key); i++)
    {
        if (isdigit(key[i]) == 0)
        {
            return false;
        }
    }
    return true;
}

string encrypt(string plain, int k)
{
    for (int i = 0; i < strlen(plain); i++)
    {
        if (isalpha(plain[i]) != 0)
        {
            if (islower(plain[i]) != 0)
            {
                c[i] = ((plain[i] - 97 + k) % 26) + 97;
            }
            else
            {
                c[i] = ((plain[i] - 65 + k) % 26) + 65;
            }
        }
    }
    return c;
}

您需要為c分配內存。

string encrypt(string plain, int k)
{
    c = malloc(strlen(plain) + 1);

    for (int i = 0; i < strlen(plain); i++)
    {
        if (isalpha(plain[i]) != 0)
        {
            if (islower(plain[i]) != 0)
            {
                c[i] = ((plain[i] - 97 + k) % 26) + 97;
            }
            else
            {
                c[i] = ((plain[i] - 65 + k) % 26) + 65;
            }
        }
    }
    return c;
}

main()你應該添加free(c); return 0;

在文件范圍內聲明的變量c

string c;

是一個空指針。 上面的聲明等價於

char *c;

或者實際上

char *c = NULL;

所以在函數中使用空指針encrypt就像

c[i] = ((plain[i] - 97 + k) % 26) + 97;

調用未定義的行為。

當像encrypt這樣的函數依賴於全局變量時,這也是一個壞主意。

還使用像97這樣的幻數會使程序不清楚。

由於函數參數沒有限定符const ,因此將傳遞的字符串就地轉換是合乎邏輯的。

請注意,用戶可以傳遞一個非常大的整數值作為鍵。 在這種情況下,您的函數將調用未定義的行為。

所以函數看起來像

string encrypt( string plain, int k)
{
    k = k % 26;

    for ( size_t i = 0, n = strlen( plain ); i < n; i++ )
    {
        if ( isalpha( ( unsigned char )plain[i] ) )
        {
            if ( islower( plain[i] ) )
            {
                plain[i] = ( plain[i] - 'a' + k ) % 26 + 'a';
            }
            else
            {
                plain[i] = ( plain[i] - 'A' + k ) % 26 + 'A';
            }
        }
    }

    return plain;
}

變量c應該被刪除,在 main 中寫就足夠了

string p = get_string( "plaintext: " );
puts( encrypt( p, atoi( argv[1] ) ) );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM