[英]Why does the output of the code changes, when printing a random text with printf?
以下代碼將輸入的字母更改為 k。 k 是第一個參數。 例如,如果輸入應更改 2 個字母,則命令行參數將是“./caesar 2”,如果是三個則“./caesar 3”。 等等。改變字母的意思是,例如改變2,然后輸入'a'變成'c'。 更改 3 意味着輸入“abc”變為“def”等。如果(a)數字參數是精確的 2,(b)參數是數字,則正在檢查用戶提供的輸入。
當代碼寫在輸出下方時執行的代碼被縮短了一個字母。 例如,“hello”改變了 1 個字母就變成了“iffm”。 如果只輸入一個字母,它會顯示正確的輸出,然后是一些未定義的字母。 例如,'a' 變為 "b P" 或 "bm> " 或 "b; "。
當 (1) 輸入檢查 (b) [如果參數是一個數字] 被刪除或 (2) 一個帶有隨機語句的 printf 行(它甚至可以是一個空字符串)被准確地插入到 get_string 函數之間時,當要求用戶輸入和 for 循環,當更改字母時,輸出符合預期。 或 (3) 如果輸入的最后一個字符是特殊字符,則輸出符合預期(特殊字符是任何非字母字符)。 例如,“hello1”或“hello!” 改變一個字母變成“ifmmp1”或“ifmmp!”。
我真的很絕望,我不知道發生了什么,更重要的是為什么會發生這種情況。 所以我的問題是:(1)為什么輸出縮短了一個字母? 當輸入只有一個字母時,為什么輸出錯誤? (我想這是同樣的問題)。 (2) (a) 為什么在刪除數字檢查或 (b) 在上述行之間正好插入隨機 printf 行或 (c) 最后一個字符是非字母字符時輸出會發生變化?
我真的很感謝任何幫助,請原諒任何奇怪的英語,因為它不是我的母語:)。 非常感謝! 一個絕望的代碼學習者:)
這是代碼:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool isNumber(string numberToCheck);
int main(int argc, string argv[])
{
// checking, if arguments are correct
// checking, if input is correct (i.e. 2)
if(argc != 2)
{
printf("Usage: ./cesar key\n");
exit(1);
}
// checking, if input is a number, if the following if statement is removed the output changes
if(!isNumber(argv[1]))
{
printf("Usage: ./caesar key\n");
exit(1);
}
// variables
int k = atoi(argv[1]);
string plaintext;
int plaintextLength;
// getting the plaintext from user input, creating ciphertext string of same length
plaintext = get_string("paintext: ");
// checking the length of the input
plaintextLength = strlen(plaintext);
//the output changes, when the next line is being inserted
printf("");
// creating new empty string with plaintextLength
char ciphertext[plaintextLength];
// iterating through plaintext char by char
for(int i = 0; i < plaintextLength;i++)
{
// in case of capital letter
if(plaintext[i] >= 65 && plaintext[i] <= 90)
{
ciphertext[i] = 65 + (((plaintext[i] - 65) + k) % 26);
}
// else in case of small letter
else if(plaintext[i] >= 97 && plaintext[i] <= 122)
{
ciphertext[i] = 97 + (((plaintext[i] - 97) + k) % 26);
}
// else in case of non alphabetical letter
else
{
ciphertext[i] = plaintext[i];
}
}
printf("ciphertext: %s\n", ciphertext);
}
bool isNumber(string numberToCheck)
{
for(int i = 0;i < strlen(numberToCheck); i++)
{
if(!isdigit(numberToCheck[i]))
{
return false;
}
}
return true;
}
int i;
// iterating through plaintext char by char
for(i = 0; i < plaintextLength;i++)
{
// in case of capital letter
if(plaintext[i] >= 65 && plaintext[i] <= 90)
{
ciphertext[i] = 65 + (((plaintext[i] - 65) + k) % 26);
}
// else in case of small letter
else if(plaintext[i] >= 97 && plaintext[i] <= 122)
{
ciphertext[i] = 97 + (((plaintext[i] - 97) + k) % 26);
}
// else in case of non alphabetical letter
else
{
ciphertext[i] = plaintext[i];
}
}
ciphertext[i] = '\0';
printf("ciphertext: %s\n", ciphertext);
}
在 C 中,每個字符串都使用 \\0 來告訴計算機它已到達字符串的末尾。
如果沒有這個 NULL 終止運算符,計算機可能會嘗試將字符串讀入內存,這就是您遇到隨機符號的原因。
因此,當您創建字符串時,請確保在其末尾添加 \\0,這就是我在這里對您的代碼所做的。 我在 for 循環外聲明了“i”,它在循環結束時不會停止存在。 當您到達循環末尾時,“i”將等於字符串的長度。
如果我的明文是“lol”,密鑰是 5,“i”將等於 3,密文將是“qtq”。 Ciphertext[i] 將指向最后一個“q”之后,因為我們從 0 開始計數,這是您想要放置 \\0 的位置。
您的 getstring 中還有一個錯字。
希望我的解釋清楚,如果您有任何問題,請提出:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.