我希望这不是一个问题的火鸡。我检测EOF的条件似乎不起作用。代码继续通过EOF和语句中的进程。当我重新创建文本时,它显示得恰当,但是整个bmp与垃圾代码也打印出来告诉我文本标志的结尾从未被编码。我已经在下一个条件中放置了一个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;
}
答案 0 :(得分:2)
您正在为signed int
分配unsigned int
。结果将不是您所期望的结果。它将是一个值,所有位都设置为1
。 (EOF
的值为-1
,因此已签名)。
长话短说,它应该是int
。简单的int character
将达到目的。
另一件事getchar()
会返回int
。
int getchar(void);
还有其他事情要做: -
应检查fread
返回值。
size_t fread(void * restrict ptr,size_t size, size_t nmemb,FILE * restrict stream);
fread
函数成功返回元素数 读取,如果读取错误或文件结束,则可能小于nmemb
遇到了。如果size
或nmemb
为零,fread
将返回零和 数组的内容和stream
的状态 保持不变
fopen()
的返回值。如果失败,返回值将为NULL
。答案 1 :(得分:1)
这里有两个严重但常见的问题导致我相信你不会读一本声誉好的书,或者你有一个严重的问题,作为着名的书将在前面的章节中讨论这些问题。
也许我们应该看一些其他选项,因为你现在使用的任何东西显然都不适合你。你可能一直在阅读你的书,所有这些时候你都在努力进行反复试验,而你的书本应该引导你完成这些常见问题。
底线是:您需要尊重返回值。
loading
中,您要转换书籍和getchar manual
所说的内容在您尝试与unsigned char character; character = getchar();
进行核对之前int
unsigned char
。转换可能会导致数据丢失。你不知道你丢失了哪些数据?如果你正在努力理解K&amp; R2E或手册,你应该写一个你不了解的问题,而不是继续,困惑,编写依赖于猜测的代码。任何猜测都会在诸如C等语言中发生危险。
您还应该检查EOF
的返回值,并且我希望在您的案例中看到fread
参数传递54并且size
参数传递1。这样,您可以处理count
仅读取五十三字节(或五十二,或五十一)的情况)好像它是输入的结束,而不是将意外短输入视为预期的大小。与fread
手册一样,您可以从the fread
manual了解getchar
的所有内容。
哦,现在我得到了很多&#34;但Youtube视频&#34;响应。 Youtube并不是一本信誉良好的书的好替代品。任何人都可以跳到那里并且#34;只是将它放在一边#34;你观看的视频可能会像你自己的猜测一样存在缺陷。另一方面,一本着名的书已经有数千小时的时间用于计划,同行评审,测试(对学生,因为这些书通常是由也有教学课程的教授编写)和重构(基于测试,到更好地处理&#34;打嗝&#34;发生的事情。)
选择应该是显而易见的,并且证明是在吃布丁。如果你已经尝试过&#34; youtube&#34;或者&#34;尝试看看&#34;方法,他们不适合你;你现在所看到的就是你的结果。尝试其他的东西。祝你好运!