簡體   English   中英

使用 printf 打印隨機文本時,為什么代碼的輸出會發生變化?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM