我是 C 的新手,我正在練習一些代碼以提高我的知識。
使用以下代碼,我試圖加密給定的文本,為每個文本字符回傳一個字符,該字符是在字母表中向前移動 n 個位置的結果。
因此,例如,對于給定的文本“hello”和密鑰 6(因此,對于 'hello' 的每個字符在字母字符陣列中移動 6 個位置),加密文本將是“nkrru”。

我的代碼使用:
- 空字符陣列 strResult 將生成的加密文本存盤在哪里;
- 臨時字符陣列 tmp 存盤移位字符的位置。
我還使用了兩個嵌套回圈:在第一個回圈中,我逐個字符地迭代到給定的文本字串中,而在內部回圈中,我迭代到字母字符中以找到等效的字符。然后我用按關鍵時間移動的字母字符填充 tmp 陣列。
同時,如果向前移動超過了字母表的 26 個字母并且其中一個字符是空格,我會處理這種情況。
最后,我使用 strcat() 將 tmp 連接到 strResult 并列印它。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char ALPHABET[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
int key = 9;
string word = "Hello World";//text to encrypt
char resultStr[strlen(word)];//string where to store the resulting encrypted text
char tmp[strlen(word)];//temporary string
int counter;//for the shifted index
for (int i = 0, n = strlen(word); i < n; i )
{
char wordcurrChar = tolower(word[i]);//convert every wordcurrChar to lowercase
int checkSpace = isspace(wordcurrChar);//check if the character is a white space
//inner loop to iterate trough alphabet array
for (int j = 0, m = strlen(ALPHABET); j < m; j )
{
counter = j key;//counter has now the value of the shifted index
char ALPHcurrChar = ALPHABET[j];
if ((wordcurrChar == ALPHcurrChar) && (counter <= 26)) {//if counter is whitin the 26 characters of the alphabet
tmp[i] = ALPHABET[counter];//then shift at index counter
} else if ((wordcurrChar == ALPHcurrChar) && (counter > 26)) {//if counter is over the 26 characters of the alphabet
int newCounter = counter - 26;//then, once over Z, start from the beginning of the alphabet
tmp[i] = ALPHABET[newCounter];
} else if (checkSpace != 0) {//if the character is a white space
tmp[i] = ' ';//then return a white space also for the encrypted text
}
}
}
strcat(resultStr, tmp);//concat resultStr and temporary string
printf("%s\n", resultStr);//print the encrypted text
}
一切看起來都很好,除了當移位超過 26 個字母字符并且必須作為加密字符回傳特定字母“A”時,它會停止。
因此,例如,如果我使用 key=9 作為字串加密hello world,結果是qnuux fx_ _ _。缺少最后 3 個字母。基本上, char r在hello wo r ld中的移動(在字母陣列中移動 9 個位置超過了第 26 個位置并以 char a位置結束)停止了一切。

Again, this happen only if the shifting goes over the 26 letters of the alphabet and end on the specific position of char a (with all other cases works fine). So with hello world and key = 15, the result will be wt_ _ _ _ _ _ _ _ stopping at the shifting of the first l of hello world. This because the shifting goes over the 26 alphabet letters and reach char a position.

I spent hours and hours to understand why is happening but with no success.
Hope someone can help.
Thanks a lot in advance.
P.s: I tried many different changing of the if statment that manage the condition of going over the 26 alphabet array positions but nothing really helped.
uj5u.com熱心網友回復:
代碼似乎忽略了使用 C 庫,字串具有'\0'
字串是由第一個空字符終止并包括第一個空字符的連續字符序列。C17dr 7.1.1 1
至少有這些問題:
strlen()在非字串上
strlen(ALPHABET)導致未定義的行為(UB) 與strlen()預期的字串一樣,并且ALPHABET不是字串,因為它缺少終止的空字符。
// Bad
char ALPHABET[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
for (int j = 0, m = strlen(ALPHABET); j < m; j )
// Add null character
char ALPHABET[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\0'};
// or simply
char ALPHABET[] = "abcde...wxyz";;
strcat()帶有非字串
同樣,strcat()以下失敗如strcat()預期resultStr并tmp成為strings。字串也不是,因為它們缺少終止空字符。
char resultStr[strlen(word)];
char tmp[strlen(word)];
....
// Bad
strcat(resultStr, tmp);
替代代碼會將陣列大小增加 1 并添加最終的'\0'.
沒有效率地反復步行word尋找它的長度。
size_t word_length = strlen(word);
char resultStr[word_length 1u];
char resultStr[0] = '\0';
char tmp[word_length 1u];
....
char tmp[word_length] = '\0';
strcat(resultStr, tmp);
uj5u.com熱心網友回復:
- 您可以簡單地使用字串初始化 char 陣列。
char ALPHABET[] = "abcdefghijklmnopqrstuvwxyz";
#define魔術數字更好
#define CIPHER_ROTATIONS 9
- 為了資料一致性,每個密碼都應該是可恢復的。因此,忽略字母大小寫會丟失資訊。
char wordcurrChar = tolower(word[i]);
簡化代碼:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define CIPHER_ROTATIONS 27
// shift can be positive(encoding) or negative(decoding)
void caeser_cipher (const char* input, const int tlen, int shift, char* output)
{
shift %= 26; // more than 26 make cycle[s]
if (shift < 0) shift = 26; // moving x steps backward = moving (26-x) forward
for (int ti=0; ti < tlen; ti) {
if (islower (input[ti]))
output[ti] = 'a' (input[ti] - 'a' shift) % 26;
else if (isupper (input[ti]))
output[ti] = 'A' (input[ti] - 'A' shift) % 26;
else
output[ti] = input[ti];
}
}
int main() {
char text[] = "Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift";
int tlen = strlen(text);
char cipher[tlen 1]; cipher[tlen] ='\0';
int shift = CIPHER_ROTATIONS; // also called rotations
printf ("Text :\t\t[%s]\n", text);
caeser_cipher (text, tlen, shift, cipher);
printf ("Cipher:\t\t[%s]\n", cipher);
text[0] = '\0';
caeser_cipher(cipher, tlen, -shift, text);
printf ("DecipheredText: [%s]\n", text);
return 0;
}
uj5u.com熱心網友回復:
非常感謝大家的幫助。正如我所寫,我是 C 的新手,可能我必須深入研究字串行為。
對我來說莫名其妙的是,腳本在這樣一個特定情況下停止,而不是在所有其他情況下停止。
我會將您的所有建議作為深入研究 c 字串問題的起點。再次感謝您的幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/449704.html
標籤:c loops encryption indexing
上一篇:按組劃分的評分者間信度
下一篇:以恒定的差異從for回圈中獲取值
