return 类型和数组大小分配问题

return type and array size assigning question

我现在正在尝试将 return 类型的函数 encrypt 更改为 char(或必要时为字符串)而不是 void。尽管这段代码已经可以运行(顺便说一句,我还有两个其他版本的代码也可以运行),但我真的很想掌握 return 类型如何运行等基本概念。另外,我想知道如何修改第 33 行 char *ciphertext = plaintext;,使数组不包含任何地址或值(例如,如果删除指针 (*))但分配大小 char *ciphertext[strlen(plaintext)]?这不是必要的修改,因为代码工作得很好,但如果我使用这种风格,并且在我需要将大量数据存储到数组中的给定情况下,它会降低速度。

所以,这是详尽无遗的。为了简单起见,这里有两个问题:

  1. 如何修改函数 encrypt return 类型为字符或字符串?
  2. 如何在不存储数据(值)的情况下使用与明文相同的指定大小初始化数组密文?

非常感谢您的帮助、回答和评论(如果我的代码风格不干净或阅读起来不愉快,请随时批评)。

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

// Trying char as a return type
void encrypt(char *plaintext, int k, char *ciphertext);

int main(int argc, char *argv[])
{
    // Validate if the user inputted the adequate value type
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // Loop for validating if each char of argv is a digit
    for (int i = 0, n = strlen(argv[1]); i < n; i++)
    {
        // if the key is not a digit, it will return 0.
        if (isdigit(argv[1][i]) == 0)
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }
    // function atoi converts key(array of char) into an integer
    int key = atoi(argv[1]);

    char *plaintext = get_string("plaintext:  ");
    char *ciphertext = plaintext;
    encrypt(plaintext, key, ciphertext);
    printf("ciphertext: %s\n", ciphertext);
    return 0;
}

void encrypt(char *plaintext, int k, char *ciphertext)
{
    while (*plaintext) {
        // Identify if the value is an alphabet
        if (isalpha(*plaintext) != 0)
        {
            // Apply formula to uppercase character
            if (isupper(*plaintext) != 0)
            {
                *ciphertext = ((*plaintext - 'A' + k) % 26) + 'A';
            }
            // Apply formula to lowercase character
            else
            {
                *ciphertext = ((*plaintext - 'a' + k) % 26) + 'a';
            }
        }
        plaintext++;
        ciphertext++;
    }
}

如评论中所述,由于将 ciphertext 设置为 NULL,因此您正在写入 NULL 指针。您要做的是为 ciphertext 分配内存。这可以通过 char *ciphertext = strdup(text); 来完成,它设置 ciphertext 新分配的指针指向名为 text 的 null-terminated 字符指针的副本。使用此解决方案或下面的解决方案,您不需要 // Store non-alphabetical value as it is 因为该值已经存在。

使用 strdup() 是一种方法,但如果您可以修改 text 本身,则有更好的选择。您可以简单地使用:

void encrypt(char *text, int k) {
    while (*text) {
        // Identify if the value is an alphabet
        if (isalpha(*text) != 0) {
            if (isupper(*text) != 0) {
                // Apply formula to uppercase character
                *text = ((*text - 'A' + k) % 26) + 'A';
            } else {
                // Apply formula to lowercase character
                *text = ((*text - 'a' + k) % 26) + 'a';
            }
        }
        text++;
    }
}

一点解释:while (*text)表示执行以下操作,直到at文本中存储的值为0。text++; 递增指针。所以在那行之后 text 指向下一个字符。所有这些只是 for (int i = 0; text[i] != '[=23=]'; i++) 但不需要新变量的另一种方式。

注意上面的代码不再是returns“加密”的结果。相反,它会修改您传递给它的 char * 的内容。无需内存分配——调用者已为您完成。

如果你选择使用上面的代码,你需要做这样的事情来打印结果:

...
char *text = get_string("plaintext:  \n");
encrypt(text, key);
printf("ciphertext: %s\n", text);
...