getc() 在主函数之外不工作

问题描述

我编写了一个小程序,它使用 XTEA 密码算法来加密或解密给定的文本文件。 一切都很好,直到我开始整理我的程序。

这是曾经可以工作的代码

int main(int argc,char *argv[]){
    char* filename = malloc(20*sizeof(uint8_t));
    uint32_t* argBuf = malloc(2*sizeof(uint32_t)); /* used to buffer (de)cypher strings */
    uint32_t* keyBuf = malloc(4*sizeof(uint32_t));      /* used to store the cypher key */
    int character,i,opt,filelen;
    FILE *finp,*fdec,*fenc;
    i = 0;
    /* get plaintext input file */
    printf("Please enter the following filenames. They\r\n");
    printf("shall be no longer than 100 characters.\r\n");
    printf("Input filename: \r\n");
    fflush(stdin);
    gets(filename);
    fflush(stdin);
    finp = fopen(filename,"r"); 
    if (finp == NULL){
        printf("Error! Input file not found!\r\n");
        return;
    }
.
. /* opening the other file(s) and other stuff not related to problem */
.

    /* iterate over file */ 
    while ((character = getc(finp)) != EOF){
        i++;
        *(((uint8_t*)argBuf) + i) = (uint8_t) character;
        if (++i == 8){
            /* encode */
            printf("\r\nnon ciphered text: ");
            printText((uint64_t*)argBuf);
            printf("\r\nciphered text: ");
            encipher(NUM_CYCLES,argBuf,keyBuf);
            storeCipherText((uint64_t*)argBuf,fenc);
            printText((uint64_t*)argBuf);
            i = 0;
            argBuf[0] = 0;
            argBuf[1] = 0;
        }
    }

}

输出(只是证明可以读取文件):

***************************************************
*              Cipher programm using XTEA         *
***************************************************

Please enter the following filenames. They
shall be no longer than 20 characters.
Input filename:
t.txt
Cipher text output file: 
aaaa
Deciphered text output file: 
t2.txt

non ciphered text: Hall
ciphered text: *j|+A
.
.
.

现在我写了一个辅助函数来处理文件的打开和读取。它包含在一个名为“HandleEncipher”的函数中:

void HandleEncipher(void){
char* filename = malloc(20*sizeof(uint8_t));
uint32_t* argBuf = malloc(2*sizeof(uint32_t)); /* used to buffer (de)cypher strings */
uint32_t* keyBuf = malloc(4*sizeof(uint32_t));     /* used to store the cypher key */
int character,i;
FILE *finp,*foutp;

/* get plaintext input file */
printf("Please enter the following filenames. They\r\n");
printf("shall be no longer than 100 characters.\r\n");
printf("Input filename: \r\n");
fflush(stdin);
gets(filename);
fflush(stdin);
finp = fopen(filename,"r"); 
if (finp == NULL){
    printf("Error! Input file not found!\r\n");
    return;
}

/* get cipher text output file */
printf("Cipher text output file: \r\n");
gets(filename);
foutp = fopen(filename,"wb");                 /* create or clear file */
if (foutp == NULL){
    printf("Error! Can't write to output file!\r\n");
    return;
}

StoreCipherKey(keyBuf);

argBuf[0] = 0;                          /* initialize buffer and index */
argBuf[1] = 0;
i = 0;

printf("start iterating");
/* iterate over file */ 
while ((character = fgetc(finp)) != EOF){
    i++;
    printf("character#: %i",i);
    *(((uint8_t*)argBuf) + i) = (uint8_t) character;
    if (++i == 8){
        /* encode */
        printf("\r\nnon ciphered text: ");
        printText((uint64_t*)argBuf);
        printf("\r\nciphered text: ");
        printText((uint64_t*)argBuf);
        storeCipherText((uint64_t*)argBuf,foutp);
        i = 0;
        argBuf[0] = 0;
        argBuf[1] = 0;
    }
}
}

一个有趣的细节是,如果我在 Visual Studio Code 中调试代码,如果使用“HandleEncipher”函数,我的 finp 变量等于 NULL。

我很困惑,因为外包代码实际上是在 main 中运行良好的代码的副本。我不知道会出什么问题(除了对输入字符串的边界检查不佳)。但是我在第二个版本中使用了与第一个版本完全相同的文件名,如果我对不存在的文件使用文件名,我的程序会做出相应的反应。

有人知道这里发生了什么吗?

解决方法

StoreCipherKey 函数:

void StoreCipherKey(uint32_t keyBuffer[4]){
    uint8_t i;
    /* fill key into buffer */
    for (i = 0; i < KEYSIZE/(2*sizeof(*keyBuffer)); i++){
        if (i < KEYSIZE/(sizeof(*keyBuffer)*2)){
            keyBuffer[i] = (uint32_t) TEST_KEY_LOWER >> (i*32);
        } else {
            keyBuffer[i-KEYSIZE/(sizeof(*keyBuffer)*2)]  = (uint32_t) TEST_KEY_UPPER >> ((i - 2*sizeof(*keyBuffer))*32);
        }
    } 
}

这里我覆盖了 keyBuffer。这会导致未定义的行为。是的,在我当前的时区,编程为时已晚。

感谢@Joshua 提示问题。