【问题标题】:How can I return String to the main function?如何将字符串返回到主函数?
【发布时间】:2022-07-05 13:33:44
【问题描述】:

目标实际上是将明文字符串中的字符替换为密文。用户使用命令行参数输入键,键输入为 26 个字母。

我在运行程序时遇到了问题,它得到了Segmentation fault (core dumped)。在调试期间,代码在功能行停止工作。我的问题是发生了什么以及如何解决这个问题以便我可以创建一串键?

这是我的代码行:

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

// Declare crypting function
string encrypt(string text, string key_upper, string key_lower);
string valid_key_upper(string key);
string valid_key_lower(string key);

int main(int argc, string argv[])
{
    // Must contain an argument
    if (argc > 2 || argc < 2)
    {
        printf(\"Usage: ./substitution KEY\\n\");
        return 1;
    }

    // take the input from the commandline and validate them.
    string key_before = argv[1];
    int key_length = strlen(key_before);

    // evaluate the key length
    if (key_length != 26)
    {
        printf(\"Key must contain 26 characters.\\n\");
        return 1;
    }


    // Create initial key container
    char key[26];
    int evaluated_key = 0;

    for (int i = 0; i < key_length; i++)
    {
        // Validate so that only letters
        if (key_before[i] < 65|| key_before[i] > 122 || (key_before[i] > 90 && key_before[i] < 97))
        {
            printf(\"Must only contain letters!\\n\");
            return 1;
        }
        // Compare the current evaluated key to the existing key in the memory
        else
        {
            for (int n = 1; n < evaluated_key; n++)
            {
                if (key_before[i] == key[n])
                {
                    printf(\"Must not contain duplicate!\\n\");
                    return 1;
                }
            }
            // copy valid key to the key container
            key[i] = key_before[i];
            evaluated_key = evaluated_key + 1;
        }
    }

    // Make lower-case and upper-case function container
    string key_upper = valid_key_upper(key);
    string key_lower = valid_key_lower(key);

    // get user input of plaintext
    string plaintext = get_string(\"Plaintext: \");

    // function for ciphering
    string ciphertext = encrypt(plaintext, key_upper, key_lower);

    // print out the ciphered text
    printf(\"Ciphertext = %s\\n\", ciphertext);

}

string valid_key_upper(string key)
{
    // Declare variable container
    string key_upper = NULL;

    // Take the key and evaluate each character
    for (int i = 0; i < 26; i++) // evaluate for 26 characters
    {
        if (key[i] >= 65 && key[i] <= 90)
        {
            key_upper[i] = key[i];
        }
        else if (key[i] >= 97 && key[i] <= 122)
        {
            key_upper[i] = toupper(key[i]);
        }
    }
    key_upper[26] = \'\\0\';
    return key_upper;
}
  • cs50 掩盖了string 只不过是typedef char* string; 的事实
  • 致 CS50 创建者/维护者:请考虑放弃伪 string 类型,除了最简单的情况外,它只会在所有情况下造成混乱。
  • 请注意:您应该避免像65 这样的幻数。请改用\'A\',这清楚地表明了您的意图。

标签: arrays c segmentation-fault cs50 c-strings


【解决方案1】:

您的问题在于valid_key_upper 中的key_upper;没有为字符串分配空间,您将其初始化为NULL,因此当您将值分配给key_upper[i] 时,您会丢弃堆栈。您必须先mallockey_upper,然后才能为其分配字符串元素。

【讨论】:

    【解决方案2】:

    您正在使用空指针来访问内存。

    例如,在函数 valid_key_upper 中,指针 key_upper 设置为 null

    string key_upper = NULL;
    

    然后在下面的 for 循环中,您尝试取消引用指针

    // Take the key and evaluate each character
    for (int i = 0; i < 26; i++) // evaluate for 26 characters
    {
        if (key[i] >= 65 && key[i] <= 90)
        {
            key_upper[i] = key[i];
            //...
    

    这会导致未定义的行为。

    没有必要创建这样的字符串。加密字符串时,您可以将当前字符转换为大写或小写。

    一般来说,您的代码可以简化。例如,而不是这个 if 语句

    if (argc > 2 || argc < 2)
    {
        printf("Usage: ./substitution KEY\n");
        return 1;
    }
    

    你可以写

    if (argc !=  2)
    {
        printf("Usage: ./substitution KEY\n");
        return 1;
    }
    

    此外,使用65122 之类的幻数也是一个坏主意。而是使用整数字符常量。这使代码更清晰。

    【讨论】:

      【解决方案3】:

      谢谢大家的回答,所以我在key_upper变量中使用了malloc,解决了这个问题。在变量中分配了 27 个字节。此外,我还简化了功能。

      string valid_key_upper(string key)
      {
          // Declare variable container
          string key_upper = malloc(27);
      
          // Take the key and evaluate each character
          for (int i = 0; i < 26; i++) // evaluate for 26 characters
          {
               key_upper[i] = toupper(key[I]);
          }
          return key_upper;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-07
        • 1970-01-01
        • 2022-10-14
        • 2012-03-27
        • 1970-01-01
        • 2013-10-13
        • 1970-01-01
        • 1970-01-01
        • 2013-10-26
        相关资源
        最近更新 更多