没有检测到EOF

时间:2017-11-23 05:06:47

标签: c eof

我希望这不是一个问题的火鸡。我检测EOF的条件似乎不起作用。代码继续通过EOF和语句中的进程。当我重新创建文本时,它显示得恰当,但是整个bm​​p与垃圾代码也打印出来告诉我文本标志的结尾从未被编码。我已经在下一个条件中放置了一个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;
}

2 个答案:

答案 0 :(得分:2)

您正在为signed int分配unsigned int。结果将不是您所期望的结果。它将是一个值,所有位都设置为1。 (EOF的值为-1,因此已签名)。

长话短说,它应该是int。简单的int character将达到目的。

另一件事getchar()会返回intint getchar(void);

还有其他事情要做: -

  • 应检查fread返回值。

    size_t fread(void * restrict ptr,size_t size, size_t nmemb,FILE * restrict stream);

  

fread函数成功返回元素数   读取,如果读取错误或文件结束,则可能小于nmemb   遇到了。如果sizenmemb为零,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;方法,他们不适合你;你现在所看到的就是你的结果。尝试其他的东西。祝你好运!