return 类型和数组大小分配问题
return type and array size assigning question
我现在正在尝试将 return 类型的函数 encrypt 更改为 char(或必要时为字符串)而不是 void。尽管这段代码已经可以运行(顺便说一句,我还有两个其他版本的代码也可以运行),但我真的很想掌握 return 类型如何运行等基本概念。另外,我想知道如何修改第 33 行 char *ciphertext = plaintext;
,使数组不包含任何地址或值(例如,如果删除指针 (*))但分配大小 char *ciphertext[strlen(plaintext)]
?这不是必要的修改,因为代码工作得很好,但如果我使用这种风格,并且在我需要将大量数据存储到数组中的给定情况下,它会降低速度。
所以,这是详尽无遗的。为了简单起见,这里有两个问题:
- 如何修改函数 encrypt return 类型为字符或字符串?
- 如何在不存储数据(值)的情况下使用与明文相同的指定大小初始化数组密文?
非常感谢您的帮助、回答和评论(如果我的代码风格不干净或阅读起来不愉快,请随时批评)。
#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);
...
我现在正在尝试将 return 类型的函数 encrypt 更改为 char(或必要时为字符串)而不是 void。尽管这段代码已经可以运行(顺便说一句,我还有两个其他版本的代码也可以运行),但我真的很想掌握 return 类型如何运行等基本概念。另外,我想知道如何修改第 33 行 char *ciphertext = plaintext;
,使数组不包含任何地址或值(例如,如果删除指针 (*))但分配大小 char *ciphertext[strlen(plaintext)]
?这不是必要的修改,因为代码工作得很好,但如果我使用这种风格,并且在我需要将大量数据存储到数组中的给定情况下,它会降低速度。
所以,这是详尽无遗的。为了简单起见,这里有两个问题:
- 如何修改函数 encrypt return 类型为字符或字符串?
- 如何在不存储数据(值)的情况下使用与明文相同的指定大小初始化数组密文?
非常感谢您的帮助、回答和评论(如果我的代码风格不干净或阅读起来不愉快,请随时批评)。
#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);
...