简体   繁体   English

操作字符串时出现分段错误

[英]Segmentation Fault While Manipulating String

I'm trying to create a Ceasar Cipher.我正在尝试创建一个凯撒密码。 For this test, I used a key of 1 and plain text of "hello."对于这个测试,我使用了 1 的键和“hello”的纯文本。 When doing so, I get the error message "Segmentation fault (core dumped)".这样做时,我收到错误消息“分段错误(核心转储)”。 I know this means I am trying to access an illegal memory location, and it's happening while calling the "encrypt" function, but that's all I know.我知道这意味着我试图访问一个非法的内存位置,并且在调用“加密”函数时发生了这种情况,但这就是我所知道的。

Depiction of the error I'm getting while debugging.描述我在调试时遇到的错误。

And here is my code.这是我的代码。

#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;
}

You need to allocate memory for 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;
}

And in main() you should add free(c);main()你应该添加free(c); before return 0; return 0;

The variable c declared in the file scope在文件范围内声明的变量c

string c;

is a null pointer.是一个空指针。 The above declaration is equivalent to上面的声明等价于

char *c;

or in fact to或者实际上

char *c = NULL;

So using the null pointer within the function encrypt like所以在函数中使用空指针encrypt就像

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

invokes undefined behavior.调用未定义的行为。

Also it is a bad idea when a function like encrypt depends on a global variable.当像encrypt这样的函数依赖于全局变量时,这也是一个坏主意。

Also using magic numbers like for example 97 makes the program unclear.还使用像97这样的幻数会使程序不清楚。

As the function parameter does not have the qualifier const then it will be logical to convert the passed string in place.由于函数参数没有限定符const ,因此将传递的字符串就地转换是合乎逻辑的。

Pay attention to that the user can pass a very big integer value as a key.请注意,用户可以传递一个非常大的整数值作为键。 In this case your function will invoke undefined behavior.在这种情况下,您的函数将调用未定义的行为。

So the function can look like所以函数看起来像

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;
}

The variable c should be removed and in main it is enough to write变量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