最近在写aes,把加密的结果存在本地文件中然后再读出来解密,因为是加密过后的十六进制数转的字符,和正常的键盘输入不太一样,然后我从文件读取的时候就出现问题了,读到一半就发现它自动停止了。
贴一下我出错时候的代码
int readStrFromFile(char* fileName, char* str) {
FILE* fp = fopen(fileName, "rb");
if (fp == NULL) {
printf("打开文件出错,请确认文件存在当前目录下!\n");
exit(0);
}
int i;
for (i = 0; i < MAXLEN && (str[i] = getc(fp)) != EOF; i++);
if (i >= MAXLEN) {
printf("解密文件过大!\n");
exit(0);
}
str[i] = '\0';
fclose(fp);
return i;
}
int clen;
char str[MAXLEN];
char fileName[64];
if (scanf("%s", fileName) == 1){
clen = readStrFromFile(fileName, str);
}
其实我之前这个也用了好久了,我之前用的时候一直没有问题,直到我今天测一组数据的时候才触发了这个异常。
那个读取的文件是这样的:
我实际上读到锲那个字后边就不读了,虽然这句前边看见还有个空格,但是扔到转十六进制的软件里,发现这俩空格还不一样。
搜了一下,有一种可能是就正好读到某个地方是EOF了,它就终止了。
解决办法是改为使用feof()。
feof()的原理:
feof()函数,并不是通过读取到文件的EOF来评判,这个文件是否为空。
对feof()来说,它的工作原理是,站在光标所在位置,向后看看还有没有字符。如果有,返回0;如果没有,返回非0。它并不会读取相关信息,只是查看光标后是否还有内容。
看上去它比getc()更适合这个场景。
所以代码现在成了这样:
int readStrFromFile(char* fileName, char* str) {
FILE* fp = fopen(fileName, "rb");
if (fp == NULL) {
printf("打开文件出错,请确认文件存在当前目录下!\n");
exit(0);
}
int i;
for (i = 0; i < MAXLEN && !feof(fp); i++){
str[i] = getc(fp);
}
i--;
// printf("文件读取时:i=%d\n",i);
if (i >= MAXLEN) {
printf("解密文件过大!\n");
exit(0);
}
str[i] = '\0';
fclose(fp);
return i;
}
因为这样实际上它还读了那个EOF的文件结束,所以我个人更倾向于最后i–; 然后在最后头补一个’\0’;
这块儿我自己理解的也不是特别清楚,可以多输出一下比对验证。