C读二进制stdin

rlb*_*usa 20 c binary stdin

我正在尝试构建一个指令管道模拟器,我开始时遇到很多麻烦.我需要做的是从stdin读取二进制文件,然后在操作数据时以某种方式将其存储在内存中.我需要一个接一个地读取正好32位的块.

我如何一次读取32位的块?其次,我如何存储它以便以后操作?

这是我到目前为止所做的,但是检查我进一步阅读的二进制块,它看起来不正确,我不认为我正在读取我需要的32位.

char buffer[4] = { 0 }; // initialize to 0
unsigned long c = 0;
int bytesize = 4; // read in 32 bits
while (fgets(buffer, bytesize, stdin)) {
  memcpy(&c, buffer, bytesize); // copy the data to a more usable structure for bit manipulation later
  // more stuff
  buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; // set to zero before next loop
}
fclose(stdin);
Run Code Online (Sandbox Code Playgroud)

我如何一次读取32位(它们都是1/0,没有换行等),我将它存储在char[]哪里,可以吗?

编辑:我能够读取二进制文件,但没有一个答案产生正确顺序的位 - 它们都被破坏了,我怀疑字节顺序和读取问题并且一次移动8位(1个字符) - 这个需要在Windows和C上工作......?

Chr*_*utz 22

你需要的是什么freopen().从联机帮助页:

如果filename是空指针,则freopen()函数将尝试将流的模式更改为mode指定的模式,就好像当前与该流关联的文件的名称已被使用一样.在这种情况下,如果对freopen()的调用成功,则不需要关闭与流关​​联的文件描述符.它是实现定义的,允许更改模式(如果有),以及在什么情况下.

基本上,你真正做的最好的是:

freopen(NULL, "rb", stdin);
Run Code Online (Sandbox Code Playgroud)

这将重新打开stdin为相同的输入流,但是在二进制模式下.在正常模式下,从stdinWindows上读取将\r\n(Windows换行)转换为单字符ASCII 10.使用该"rb"模式禁用此转换,以便您可以正确读取二进制数据.

freopen()返回一个文件句柄,但它是前一个值(在我们将它置于二进制模式之前),所以不要将它用于任何事情.之后,fread()按照已经提到的那样使用.

然而,关于你的担忧,你可能不会读"32位",但是如果你使用的fread()话,你在4 char秒内阅读(这是你在C中可以做的最好的 - char保证至少 8位但是有些历史嵌入式平台有16位char(有些甚至有18位或更差)).如果使用fgets(),则永远不会读取4个字节.您将读取至少3个(取决于它们中的任何一个是否为换行符),并且第4个字节将是'\0'因为C字符串是nul终止的并且fgets()nul终止它读取的内容(就像一个好的函数).显然,这不是你想要的,所以你应该使用fread().

  • 与往常一样,Windows是不同的.它不允许`path`参数的"NULL".见[this](http://stackoverflow.com/a/7053024/779419)评论. (4认同)
  • 不幸的是,这不适用于Windows,原因是@schieferstapel:http://msdn.microsoft.com/en-us/library/wk2h68td.aspx.-1. (3认同)

Adr*_*ian 17

考虑使用SET_BINARY_MODE宏和setmode:

#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# define SET_BINARY_MODE(handle) setmode(handle, O_BINARY)
#else
# define SET_BINARY_MODE(handle) ((void)0)
#endif
Run Code Online (Sandbox Code Playgroud)

有关SET_BINARY_MODE宏的更多详细信息:" 通过标准I/O处理二进制文件 "

关于setmode这里的更多细节:"_ setmode "


rlb*_*usa -2

我第一次就做对了,除了,我需要 ntohl ... C Endian 转换:一点一点