我试图建立一个指令流水线模拟器,我有很多的麻烦开始。 我需要做的是阅读从标准输入的二进制,然后将其存储在内存中不知何故,而我操纵数据。 我需要准确的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);
如何在32位在同一时间(他们都是1/0,没有换行等),以及我该怎么存放它,是阅读char[]
好吗?
编辑:我能够读取二进制文件,但没有一个答案产生正确的顺序位 - 他们都错位了,我怀疑字节顺序和问题读,在时间中移动8位(1个字符) - 此需要在Windows和C工作...?
Answer 1:
你需要的是freopen()
从手册页:
如果文件名是一个空指针,调用freopen()函数将试图流的模式改变为mode指定,仿佛已经使用当前与流相关联的文件的名称。 在这种情况下,与流相关的文件描述符不必如果调用freopen函数关闭()成功。 它是实现定义允许哪些模式变化(如果有的话),以及在什么情况下。
基本上,你真的可以做到最好是这样的:
freopen(NULL, "rb", stdin);
这将重新打开stdin
是相同的输入流,但在二进制模式。 在正常模式下,读取stdin
上的Windows将其转换\r\n
(换行符的Windows)与单个字符的ASCII 10.使用"rb"
模式禁用此转换,这样就可以在二进制数据正确读取。
freopen()
返回一个文件句柄,但它的前值(我们把它放在二进制模式之前),所以不要使用它的任何东西。 在此之后,使用fread()
如已经提到。
至于您的问题,但是,您可能不会在“32位”阅读,但如果您使用fread()
您将在4读取char
秒(这是你可以在C做的最好的- char
是保证至少 8位,但一些历史和嵌入式平台具有16位的char
S(有的甚至有18或更坏))。 如果您使用fgets()
你将永远不会在4个字节读取。 你会读到至少3(取决于他们中是否有新行),而第4个字节将是'\0'
,因为C字符串是空终止,并fgets()
NUL,终止其在读什么(是个不错的功能)。 显然,这是不是你想要的,所以你应该使用fread()
Answer 2:
考虑使用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
有关详细信息SET_BINARY_MODE
宏在这里:“ 通过标准I / O处理二进制文件 ”
有关详细信息setmode
这里: “_setmode ”
Answer 3:
与fgets()是所有错在这里。 它旨在通过结束行字符,而不是二进制数据端的人可读的ASCII文本,并不会得到你所需要的。
我最近做正是你想要使用什么样的read()调用。 除非你的程序已经明确关闭标准输入,第一个参数(文件描述符),你可以设置为0的恒定值标准输入。 或者,如果你是一个POSIX系统(在Linux,Mac OS X或Unix的一些其他现代变体)上,您可以使用STDIN_FILENO。
Answer 4:
我不得不从善良的人上面的各种意见拼凑答案,所以这里是一家运作完全正常的工作样本 - 仅适用于Windows,但您可以在Windows的具体的东西可能转化为您的平台。
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
#include <io.h>
#include <fcntl.h>
int main()
{
char rbuf[4096];
char *deffile = "c:\\temp\\outvideo.bin";
size_t r;
char *outfilename = deffile;
FILE *newin;
freopen(NULL, "rb", stdin);
_setmode(_fileno(stdin), _O_BINARY);
FILE *f = fopen(outfilename, "w+b");
if (f == NULL)
{
printf("unable to open %s\n", outfilename);
exit(1);
}
for (;; )
{
r = fread(rbuf, 1, sizeof(rbuf), stdin);
if (r > 0)
{
size_t w;
for (size_t nleft = r; nleft > 0; )
{
w = fwrite(rbuf, 1, nleft, f);
if (w == 0)
{
printf("error: unable to write %d bytes to %s\n", nleft, outfilename);
exit(1);
}
nleft -= w;
fflush(f);
}
}
else
{
Sleep(10); // wait for more input, but not in a tight loop
}
}
return 0;
}
Answer 5:
I don't know what OS you are running, but you typically cannot "open stdin in binary". You can try things like
int fd = fdreopen (fileno (stdin), outfname, O_RDONLY | OPEN_O_BINARY);
to try to force it. Then use
uint32_t opcode;
read(fd, &opcode, sizeof (opcode));
But I have no actually tried it myself. :)
Answer 6:
FREAD()适合最适合读取二进制数据。
是的,字符数组是OK,如果你打算处理这些逐字节。
Answer 7:
我有它正确的第一次,但我再用ntohl需要... ÇEndian的转换:点点滴滴
文章来源: C read binary stdin