C 未检测到EOF
我希望这不是一个棘手的问题。我的检测EOF的条件似乎不起作用。代码继续执行EOF和语句中的进程。当我重新创建文本时,它会适当地显示出来,但是整个带有垃圾代码的bmp也会打印出来,告诉我文本结束标志从未编码过。我已经在下一个else条件中放置了printf语句,但是它从未输入该语句进行打印。我看不出问题出在哪里,如果它就在我面前,或者是更可怕的事情。一如既往地谢谢你C 未检测到EOF,c,eof,C,Eof,我希望这不是一个棘手的问题。我的检测EOF的条件似乎不起作用。代码继续执行EOF和语句中的进程。当我重新创建文本时,它会适当地显示出来,但是整个带有垃圾代码的bmp也会打印出来,告诉我文本结束标志从未编码过。我已经在下一个else条件中放置了printf语句,但是它从未输入该语句进行打印。我看不出问题出在哪里,如果它就在我面前,或者是更可怕的事情。一如既往地谢谢你 /*****************************************************************
/*******************************************************************************
* This code is to take a text document and using steganography techniques, hide
* the text within a bmp. It will take each character of the text, parse it into
* four 2 bit pieces and inject those bits into the two least significant bits
* of each pixel color (BGR) byte as well as the line padding.
******************************************************************************/
#include <stdio.h>
/*******************************************************************************
* getIntFromArray (borrowed from class notes). Takes unsigned character array
* and assembles/returns an int value using bit shifting with OR.
******************************************************************************/
int getIntFromArray(unsigned char bytes[])
{
int n =
bytes[0] |
bytes[1] << 8 |
bytes[2] << 16 |
bytes[3] << 24;
return n;
}
/*******************************************************************************
* bitWise. Take unsigned char pointer and character, parses the character
* using bitwise manipulation and injects 2 bits into the 2 least significant
* bits of each pixel color byte as well as padding.
******************************************************************************/
void bitWise(unsigned char* bytes, char character)
{
int i;
char tmpChar;
for(i = 0; i < 4; ++i)
{
tmpChar = character;
tmpChar &= 3;
bytes[i] &= 252;
bytes[i] |= tmpChar;
character = character >> 2;
}
}
int flag = 0;
int main(int argc, char **argv)
{
char *infilename = argv[1];
char *outfilename = argv[2];
unsigned char header[54];
FILE *in = fopen(infilename, "rb");/*Command line input.*/
FILE *out = fopen(outfilename, "wb");/*Command line input.*/
int pixelWidth;
int pixelHeight;
int i;
int j;
fread(header, 1, 54, in);/* read header into array */
pixelWidth = getIntFromArray(&header[18]);
pixelHeight = getIntFromArray(&header[22]);
fwrite(header, 1, sizeof(header), out);/* write header to output file */
for(i = 0; i < pixelHeight; ++i)/*Loop to read pixel data from bmp.*/
{
for(j = 0; j < pixelWidth; ++j)
{
unsigned char bytes[4];
unsigned char character = 0;
fread(&bytes, 1, 4, in);/*Reads sequentially pixel and padding bytes.*/
if(flag == 0)/*Breakout flag, initially set to 0.*/
{
character = getchar();/*Takes in characters from stdin.*/
if(character != EOF)/*Breakout if EOF.*/
{
bitWise(bytes, character);
}
else
{
bitWise(bytes, 0);/*Sets end of hidden text with 4 bytes LSB to 0.*/
flag = 1;
}
}
fwrite(&bytes, 1, 4, out);
}
}
fclose(in);
fclose(out);
return 0;
}
/*******************************************************************************
*这段代码是采取一个文本文档,并使用隐写技术,隐藏
*bmp中的文本。它将获取文本的每个字符,将其解析为
*四个2位片段,并将这些位注入两个最低有效位
*每个像素颜色(BGR)字节以及行填充。
******************************************************************************/
#包括
/*******************************************************************************
*getIntFromArray(从课堂笔记中借用)。接受无符号字符数组
*和使用带或的位移位来汇编/返回一个int值。
******************************************************************************/
int getIntFromArray(无符号字符字节[])
{
int n=
字节[0]|
字节[1]您正在将有符号int
赋值给无符号int
。结果将不是您期望的结果。它将是一个所有位都设置为1
的值(EOF
具有值-1
,因此它是有符号的)
长话短说,它应该是int
。简单的int字符
就可以了
还有一件事getchar()
返回int
。
intgetchar(void);
其他事情很少:-
fread
应检查返回值
size\u t fread(void*restrict ptr,size\u t size,size\t nmemb,FILE*restrict stream);
fread
函数成功返回元素数
读取,如果读取错误或文件结束,则可能小于nmemb
遇到。如果size
或nmemb
为零,fread
返回零和
数组的内容和流的状态
不变
- 另一件事是检查
fopen()
的返回值。如果失败,返回值将为NULL
您正在将有符号整数
赋值给无符号整数
。结果将不是您期望的结果。它将是一个所有位都设置为1
的值(EOF
具有值-1
,因此它是有符号的)
长话短说,它应该是int
。简单的int字符
就可以了
还有一件事getchar()
返回int
。
intgetchar(void);
还有几件事要做:-
fread
应检查返回值
size\u t fread(void*restrict ptr,size\u t size,size\t nmemb,FILE*restrict stream);
fread
函数成功返回元素数
读取,如果读取错误或文件结束,则可能小于nmemb
遇到。如果size
或nmemb
为零,fread
返回零和
数组的内容和流的状态
不变
- 另一件事是检查
fopen()
的返回值。如果失败,返回值将为NULL
这里有两个严重但常见的问题,这让我相信你没有读一本有名气的书,或者你在读这本书时遇到了严重的问题,因为这本有名气的书会在前面的章节中介绍这些问题
也许我们应该看看其他的选择,因为你现在使用的任何东西显然都不适合你。你可能一直在阅读你的书,你一直在努力尝试错误,你的书应该很好地引导你克服这些常见问题
底线是:您需要尊重返回值
- 在检查返回值之前不要尝试转换它们。在
无符号字符中;character=getchar()
您正在将书本上显示的int
转换为无符号字符
,然后再根据EOF
检查。这种转换可能会导致数据丢失。您是否想知道丢失了哪些数据
如果你正在努力理解K&R2E或手册,你应该写一个你不理解的问题,而不是继续困惑,去编写依赖于猜测的代码。任何猜测在C等语言中都是危险的
您还应该检查fread
的返回值,我希望在您的案例中看到size
参数传递了54,而count
参数传递了1。这样,您就可以处理fread
仅读取53个字节(或52个或51个)的情况就好像它是输入的结束,而不是将意外的短输入当作它是预期的大小。就像getchar
手册一样,您可以从中找到有关fread
的所有信息
哦,现在我收到了很多“但是Youtube视频”的回复。Youtube并不能很好地替代一本有名气的书。任何人都可以跳到那里“随机应变”,而你看的视频可能和你自己的猜测一样有缺陷。另一方面,一本有名气的书已经投入了数千小时的时间