C中的Caesar加密



你好,我正在开发Caesar加密程序。现在,它将带有要加密的消息的文件,即密钥作为输入

输入当前为以下格式:

"text.txt"ccc";

我需要把它转换成一个数字,这样它就符合我的要求,所以类似这样的东西:

"text.txt"3〃;

然后我需要转换这个";3〃;回到";ccc";以便程序仍然工作。逻辑是3翻译成字母表的第三个字母"1";c";,并且重复3次。另一个例子是如果输入的键是"0";2〃;,它应该返回";bb";。

到目前为止,这就是我所拥有的,但它给了我很多警告,并且该功能无法正常工作。

#include <stdio.h>
void number_to_alphabet_string(int n) {
char buffer[n];
char *str;
str = malloc(256);
char arr[8];
for(int i = 0; i < n; i++) {
buffer[i] = n + 64;
//check ASCII table the difference is fixed to 64
arr[i] = buffer[i];
strcat(str, arr);
}
printf(str);
}
int main(int argc, char *argv[]) {
const char *pt_path = argv[1];  //text.txt
char *key = argv[2];    //3
number_to_alphabet_string((int)key); //should change '3' to 'CCC'
}

您的问题是您有一个函数

void number_to_alphabet_string(int n) 

它需要一个int,但你用char*调用它

char* key = argv[2];    //3
number_to_alphabet_string(key);

我的编译器说

1>C: \work\ConsoleApplication3\ConsoleApplication 3.cpp(47,34):警告C4047:"function":"int"与"char*"的间接级别不同

您需要

char* key = argv[2];    //3
number_to_alphabet_string(atoi(key));

将该字符串转换为数字

对于char *key = argv[2];,强制转换(int) key不会将该字符串的内容重新解释为有效整数。该强制转换的作用是获取key指针值,并将该解释为整数。这样做的结果是实现定义的,如果结果不能用整数类型表示,则是未定义的(如果是sizeof (int) < sizeof (char *),则可能是结果)。

C标准没有定义这些值的任何含义。

以下是一个测试程序,根据您的平台,它应该让您了解正在发生(或没有发生)的情况

#include <stdio.h>
int main(int argc, char **argv) {
if (sizeof (long long) >= sizeof (char *))
printf("Address %p as an integer: %lld (%llx)n",
(void *) argv[0],
(long long) argv[0],
(long long) argv[0]);
}

作为实现定义行为的一个例子,在我的系统上,它打印出类似的东西

Address 0x7ffee6ffdb70 as an integer: 140732773948272 (7ffee6ffdb70)

在我的系统中,将相同的指针值强制转换为(int)会导致未定义的行为。

请注意,intptr_tuintptr_t是将指针值视为整数的适当类型,但这些类型是可选的


要将字符串实际转换为整数,可以使用atoistrtolsscanf等函数。每种方法都有其优缺点,以及处理/报告不良输入的不同方法。

没有错误处理的示例:

int three = atoi("3");
long four = strtol("4", NULL, 10);
long long five;
sscanf("5", "%lld", &five);

number_to_alphabet_string存在一些问题。

malloc可以失败,返回NULL。您应该做好处理此事件的准备。

如果malloc成功,其内存的内容将不确定。这意味着,在将内存传递给类似strcat的函数之前,您需要初始化(至少部分)内存,该函数需要一个正确的以null结尾的字符串。照原样,strcat(str, arr);将导致未定义的行为。

此外,在使用完malloc分配的内存后,应该将其与free解除分配,否则会造成内存泄漏。

char *foo = malloc(32);
if (foo) {
foo[0] = '';
strcat(foo, "bar");
puts(foo);
free(foo);
}

通常,strcat和附加缓冲器是不必要的。特别是使用char arr[8];是不安全的,因为如果n足够大,arr[i] = buffer[i];可以很容易地越界访问数组。

此外,在strcat(str, arr);中,arr也从未被空终止(更多UB)。

还要注意,printf(str);通常是不安全的。如果str包含格式说明符,那么当没有提供匹配的参数时,您将再次调用未定义的行为。使用printf("%s", str),或者可能使用puts(str)


据我所知,您只需将整数值n转换为大写字符,如果A=1,B=2并重复CCD_ 30次。

首先,不需要任何类型的缓冲区。

void number_to_alphabet_string(int n) {
if (1 > n || n > 26)
return;
for (int i = 0; i < n; i++)
putchar('A' + n - 1);
putchar('n');
}

当通过5时,将打印EEEEE

如果要创建字符串,请确保终止字符有一个额外的字节,并且该字节已设置。calloc可用于在分配期间将缓冲区清零,有效地将其终止为空。

void number_to_alphabet_string(int n) {
if (1 > n || n > 26)
return;
char *str = calloc(n + 1, 1);
if (str) {
for (int i = 0; i < n; i++)
str[i] = 'A' + n - 1;
puts(str);
free(str);
}
}

请注意,实际上并不需要动态内存。CCD_ 34将足以作为函数的持续时间的缓冲器

粗略的main用于以下任一项:

#include <stdio.h>
#include <stdlib.h>
void number_to_alphabet_string(int n);
int main(int argc, char *argv[]) {
if (argc > 1)
number_to_alphabet_string(atoi(argv[1]));
}

请注意,对于无效字符串,atoi只是返回0,这与有效的"0"无法区分——这有时是一种不利的行为

  1. 不能使用强制转换从char数组强制转换为int,必须使用函数,如atoi()
  2. 分配str后,您永远不会释放它。当您不再需要它时,应该使用free(str)。否则,它会导致内存泄漏,这意味着malloc()的内存将一直被占用,直到您的进程终止。C没有垃圾收集,所以你必须自己做
  3. 不要写char buffer[n];之类的东西,它可以通过GCC的编译,但在MSVC中不能。这并不是声明可变长度数组的标准方法。使用
char* buffer = malloc(n);
//don't forget to free() in order to avoid a memory leak
free(buffer);

相关内容

  • 没有找到相关文章

最新更新