【问题标题】:C Gives strange output when variable scope changesC在变量范围改变时给出奇怪的输出
【发布时间】:2018-09-30 03:30:42
【问题描述】:
当我将 nonAlphaCount 声明放在 for 循环之上时,

C 会做一些令人毛骨悚然的事情。我无法解释为什么输出不同。

对于版本 1(主方法上方的 int 声明),我的输入输出为: 输入:./Vigenere.exe 培根 输入纯文本:上午 11 点在公园见 输出: Negh zf av huf pcfx bt gzrwep oz

对于版本 2(上面的 int 声明 for loop ) 输入:./Vigenere.exe 培根 输入纯文本:上午 11 点在公园见 输出:NRQQ M[L \M^^ KQXXZQZ M

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>

const int INPUT_LEN = 255; 
const int ALPHABET_LEN = 26;
int nonAlphaCount = 0;

int main (int count, char *args[])
{

    char plainText[INPUT_LEN];
    char *cipherText;
    char *keyWord;

    if ( count < 2 || count > 2)
    {
        printf("There is no key");
        return 1;
    }

    strcpy(keyWord, args[1]);
    int keyWord_LEN = strlen(keyWord);

    printf("Enter plain text: ");
    fgets (plainText, INPUT_LEN, stdin);

    int strLength = strlen(plainText);
    cipherText = malloc(strLength);

    printf("%s", plainText);

    for (int i = 0; i < strLength; i++ ){

        if(plainText[i] == '\0' || plainText[i] == '\n'|| plainText[i] == '\r')
            break;

        if(isalpha(plainText[i]))
        {
            // Default lower 
            int asciiUpperOrLower = 97;   
            int keyUpperOrLower = 97;    

            if(isupper(plainText[i]))
                asciiUpperOrLower = 65;

            if(isupper(keyWord[i % keyWord_LEN]))
                keyUpperOrLower = 65;

            int Key = keyWord[(i - nonAlphaCount) % keyWord_LEN] - keyUpperOrLower;
            int alphabetBaseletter = ((plainText[i] - asciiUpperOrLower + Key) % ALPHABET_LEN);

            cipherText[i] = alphabetBaseletter + asciiUpperOrLower;
        }
        else{
            cipherText[i] = plainText[i];
            nonAlphaCount++;
        }

    }

    // Set string terminator.
    cipherText[strLength - 1] = '\0' ;

    printf("%s", cipherText);

    return 0;

}





#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>

const int INPUT_LEN = 255; 
const int ALPHABET_LEN = 26;

int main (int count, char *args[])
{

    char plainText[INPUT_LEN];
    char *cipherText;
    char *keyWord;

    if ( count < 2 || count > 2)
    {
        printf("There is no key");
        return 1;
    }

    strcpy(keyWord, args[1]);
    int keyWord_LEN = strlen(keyWord);

    printf("Enter plain text: ");
    fgets (plainText, INPUT_LEN, stdin);

    int strLength = strlen(plainText);
    cipherText = malloc(strLength);

    printf("%s", plainText);

**int nonAlphaCount = 0;**
    for (int i = 0; i < strLength; i++ ){

        if(plainText[i] == '\0' || plainText[i] == '\n'|| plainText[i] == '\r')
            break;

        if(isalpha(plainText[i]))
        {
            // Default lower 
            int asciiUpperOrLower = 97;   
            int keyUpperOrLower = 97;    

            if(isupper(plainText[i]))
                asciiUpperOrLower = 65;

            if(isupper(keyWord[i % keyWord_LEN]))
                keyUpperOrLower = 65;

            int Key = keyWord[(i - nonAlphaCount) % keyWord_LEN] - keyUpperOrLower;
            int alphabetBaseletter = ((plainText[i] - asciiUpperOrLower + Key) % ALPHABET_LEN);

            cipherText[i] = alphabetBaseletter + asciiUpperOrLower;
        }
        else{
            cipherText[i] = plainText[i];
            nonAlphaCount++;
        }

    }

    // Set string terminator.
    cipherText[strLength - 1] = '\0' ;

    printf("%s", cipherText);

    return 0;

}

【问题讨论】:

  • 请发布一个最小的、完整的和可验证的问题示例stackoverflow.com/help/mcve
  • strcpy(keyWord, args[1]); 将字符串复制到一个未初始化的变量中,您需要 cipherText = malloc(strLength + 1) 来说明字符串中的终止 0。 if ( count != 2)if ( count &lt; 2 || count &gt; 2) 更容易输入,也更清晰。
  • Oke true if (count != 2) 肯定更好,我也将未初始化的变量更改为。 char *cipherText = malloc(strLength + 1);但是变量 nonAlphaCount 的作用域声明位置仍然对输出有影响。为什么?
  • 您没有阅读我的评论和答案中最重要的部分。您的 keyword 变量未初始化。一旦你复制到那个变量,所有关于你的程序会做什么的赌注都没有了。
  • @RetiredNinja 你说得对,我用这行代码解决了问题 char *keyWord = malloc(strlen(args[1]));。我仍然很难理解为什么。我想我还有一些阅读要做。

标签: c


【解决方案1】:

两个程序都表现出未定义的行为

char *keyWord;
...
strcpy(keyWord, args[1]);

编译器警告显示:“使用了未初始化的局部变量'keyWord'”。您还没有分配任何内存。

如果其中一个程序碰巧有效,那就这样吧。

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多