gpt4 book ai didi

C - strcpy() 和 strncpy() 缓冲区溢出

转载 作者:行者123 更新时间:2023-11-30 18:29:09 27 4
gpt4 key购买 nike

我正在 edx 上学习 CS50 类(class),我应该用 C 语言编写一段代码,使用维吉尼亚密码对消息进行加密。我做到了。但问题是我不断遇到缓冲区溢出。

如果我使用短字符串,例如“Meet”,则效果很好。但是,如果我使用较长的字符串,例如“上午十一点在公园见我”,则会出现缓冲区溢出问题。

如果我使用 strcpy()argv[1] 中传递的 key 复制到另一个变量(比方说 k),并且原始消息 (msg) 到加密消息的变量 (encMsg),然后它会删除我在 k 中的内容。如果我再次使用 strcpy()argv[1] 的值复制到 k 一次,我会在 中遇到缓冲区溢出>encMsg 连接两个字符串。

如果我使用strccpy(),它不会删除k的内容,但它会溢出并连接encMsg上的两个字符串。

当我使用 GetSting() (来自 cs50.h)时,这一切都会发生;

如果我使用fgets(),那么我将在消息末尾得到'\n',然后必须添加一个if来将'\0'放在'\n'的位置是,这解决了我的问题,但我想知道是否有人可以解释为什么会发生这一切。

这是我的代码:

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


int main(int argc, char *argv[])
{
if (argc != 2) //Checks if number of command-line arguments is valid
{
printf ("usage: ./caesar + key \n");
return 1;
}

char k[strlen(argv[1])];
//strcpy(k, argv[1]); //Saves argument into a string
strncpy(k, argv[1], strlen(argv[1]));

for (int x = 0; x < strlen(k); x++)
{
if (k[x] < 65 || (k[x] > 90 && k[x] < 97) || k[x] > 122) //Checks if there is any non-alphabetical character in key
{
printf ("key must contain only alphabetical characters \n");
return 1;
}
}

//printf("Inform the message you want to encrypt: \n");
string msg = GetString();
//char msg[255];
//fgets(msg, 255, stdin);

char encMsg[strlen(msg)];
//strcpy(encMsg, msg);
strncpy(encMsg, msg, strlen(msg));

//strcpy(k, argv[1]);

int y = 0;
for (int x = 0; x < strlen(msg); x++)
{
//if(msg[x] == '\n') msg[x] = '\0';
if (msg[x] < 65 || (msg[x] > 90 && msg[x] < 97) || msg[x] > 122) encMsg[x] = msg[x];
else if ((msg[x] + (k[y] - 97 ) > 90 && msg[x] + (k[y] - 97 ) < 97) || msg[x] + (k[y] - 97 ) > 122)
{
encMsg[x] = msg[x] + (k[y] - 97) - 26;
y++;
}
else
{
encMsg[x] = msg[x] + (k[y] - 97);
y++;
}
if (y >= strlen(k)) y = 0;
}

printf("key = %s\n", k);
printf("msg = %s\n", msg);
printf("encMsg = %s\n", encMsg);


return 0;
}

最佳答案

这种代码风格:

char k[strlen(argv[1])];

不为终止'\0'字符留下空间。应该是

char k[strlen(argv[1]) + 1 ];

正如评论中指出的,代码如

strncpy(k, argv[1], strlen(argv[1]));

将无法正确终止目标字符串。每the standard for strncpy() :

If the array pointed to by s2 is a string that is shorter than n bytes, NUL characters shall be appended to the copy in the array pointed to by s1, until n bytes in all are written.

由于目标字符串短于n,因此仅复制源字符串中的非NUL字节,因为有其中 n 个。

正确的代码可能是

strncpy(k, argv[1], 1 + strlen(argv[1]));

关于C - strcpy() 和 strncpy() 缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40911476/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com