繁体   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