我正在EDX CS50課程,我應該寫一個C代碼,使用Vigenere密碼加密消息。我做到了。但問題是我不斷收到緩衝區溢出。C - 緩衝區溢出與strcpy()和strncpy()
如果我使用短字符串,如「Meet」,它可以正常工作。但是如果我使用更長的字符串,比如「上午11點在公園與我會面」,我會遇到緩衝區溢出。
如果我使用strcpy()
同時複製在argv[1]
傳遞到另一個變量鍵(假設k
)和原始消息(msg
)的加密消息(encMsg
)的變量,然後將它刪除了我必須在k
。 如果我再次使用strcpy()
將argv[1]
的值複製到k
再一次,我在encMsg
連接兩個字符串時發生緩衝區溢出。
如果我使用strccpy()
,它將不會獲得k的內容擦除,但它會溢出並連接encMsg
上的兩個字符串。
這一切都發生在我使用GetSting()
(來自cs50.h);
如果我使用fgets()
,那麼我會在msg結尾處得到'\ n',然後必須添加一個if以在'\ n'處放置'\ 0',這解決了我的問題,但我想知道是否有人能解釋我爲什麼會發生這種情況。
這裏是我的代碼:
#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;
}
'如果(K [X] <65 ||(K [X]> 90 && K [X] <97)|| K [X]> 122)'是有標準C函數的原因,如'isalpha()','isupper()'和'islower()'。 –
哦,非常感謝@Olaf。這是一個非常好的答覆。但下一次,爲自己節省麻煩。 –
@AndrewHenle謝謝,朋友。我對C相當陌生,所以我不知道這些。 –