C++ 从二进制文件读取

C++ 从二进制文件读取,c++,C++,我正在尝试从二进制文件中计算0和1的数量。问题是,我得到了正确的零的数量,但是一等于零的数量。 我正在做的是逐字符读取文件。因为最多可以有256个字符,所以我将结果存储在一个临时数组中,用于0和1,并在再次出现字符时从中检索 #include<iostream> #include<cstdio> #include<cstdlib> using namespace std; void func(int* a1 ,int* a2) { for(int i=

我正在尝试从二进制文件中计算0和1的数量。问题是,我得到了正确的零的数量,但是一等于零的数量。 我正在做的是逐字符读取文件。因为最多可以有256个字符,所以我将结果存储在一个临时数组中,用于0和1,并在再次出现字符时从中检索

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
void func(int* a1 ,int* a2)
{
    for(int i=0;i<256;i++)
    for(int j=0;j<8;j++)
    {
        if( (i & 1) ==1 )
        {
            a1[i]+=1;
        }
        else if( (i & 1) ==0 )
        {
            a2[i]+=1;   
        }
        i>>1;
    }
}
int main()
{
    int zero[256];
    int one[256];
    int tzero[256];
    int tone[256];
    for(int i=0;i<256;i++)
    {
        zero[i]=0;
        one[i]=0;
        tzero[i]=0;
        tone[i]=0;
    }
    func(tone,tzero);
    FILE* input;
    FILE* output;
    output=fopen("ascii.txt","w");
    input=fopen("one.bin","r");
    int c;
    while((c=fgetc(input))!=EOF)
    {
        fprintf(output,"%d\n",c);
        zero[c]+=tzero[c];
        one[c]+=tone[c];
    }
    int zeroes=0;
    int ones=0;
    for(int i=0;i<=255;i++)
    {
        zeroes+=zero[i];
        ones+=one[i];
    }
    cout<<"zeroes:"<<zeroes<<endl;
    cout<<"ones:"<<ones<<endl;
    fclose(input);

    fclose(output);

}
#包括
#包括
#包括
使用名称空间std;
无效函数(int*a1,int*a2)
{
对于(int i=0;i1;
}
}
int main()
{
整数零[256];
int-one[256];
int tzero[256];
int-tone[256];

对于(int i=0;i计数0和1的循环通过执行以下操作破坏
c
的值

c >>= 1;
所有八次换档完成后,
c
始终为零,因此以下代码会增加错误计数:

// The value of c is always zero
tzero[c]=z;
tone[c]=o;
one[c]+=tzero[c];
zero[c]+=tzero[c];
您应该在位计数循环之前保存
c
的值,并在循环结束后恢复该值

更好的方法是,预先计算
tzero[]
tone[]
的值,而不必等待它们出现在文件中。这将使主循环的主体非常简短和干净:

while((c=fgetc(input))!=EOF) {
    one[c] += tzero[c];
    zero[c] += tzero[c];
}

<>如果您的目标仅是按位计数<代码> 1 < /C>和 0 位,则可以使用C++文件流来简化事情,而不使用查找表:

#include <iostream>
#include <fstream>

int main(int argc, char** argv)
{
  std::ifstream fpInput("Input.txt");
  unsigned unOnes = 0;
  unsigned unZeros = 0;
  char chTemp;

  chTemp = fpInput.get();
  while (fpInput.good())
  {
    for (unsigned i = 0; i < 8; ++i)
    {
      if (chTemp & 0x1<<i) unOnes++;
      else unZeros++;
    }

    chTemp = fpInput.get();
  }

  fpInput.close();

  std::cout << "Found " << unOnes << " ones." << std::endl;
  std::cout << "Found " << unZeros << " zeros." << std::endl;

  return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
std::ifstream fpInput(“Input.txt”);
无符号UNONE=0;
无符号非零=0;
char-chTemp;
chTemp=fpInput.get();
while(fpInput.good())
{
for(无符号i=0;i<8;++i)
{

如果(chTemp&0x1)您问题的第二句话表明您没有任何问题。您希望
c
取什么值?“没有一个值等于没有一个值”你到底在说什么?为什么这段代码如此复杂?这是一个非常简单的问题!你甚至不需要分别计算零和一;
one=(文件大小以字节为单位*8)-零
。为什么会有巨大的数组?除了文件句柄之外,您只需要两个变量:一个计数和一个临时变量来保存刚刚读取的字节。此外,过度使用“no”作为“number”这样,我真的想跳过这个问题。@user2733715你能用代码更新编辑这个问题吗?@Sebastian Redl..文件大小可能很大…因此无法避免查找表会避免重新计算。@Anshul如果你关心速度,那么我建议(首先是为了清楚起见)用C++读取文件命令替换C读取文件命令,并将文件内容加载到缓冲区中。当前按字符读取文件的方法可能会很慢。@ Anshul为256字节的随机数据,我测量了两个程序执行1000次的执行时间。(对程序进行一些小的调整以使其正常工作)。你的程序花了1.7秒,我的程序花了1.8秒,这是非常相似的,特别是考虑到我写我的程序时没有考虑优化。我的程序的附加优点是我可以给它一个10GB的文件,它仍然会运行,你的需要进一步调整,如果你打算将整个文件内容存储在内存中,你的prGram可能无法运行。无论如何……专注于编写易于阅读的代码,优化后一种代码。感谢您的建议。但您能解释一下为什么我的程序不能运行10GB的文件吗?@Anshul您的程序需要将整个文件加载到内存中。在您当前的实现中,您正在使用堆栈上的内存()它有一个有限的限制。你可以重写你的程序来使用堆,但我建议把你的文件分成可管理的块(这可以通过使用
fpInput.read(buffer,buffer\u size)
,或者C等价物来完成)。您可以使用未优化的方法(如在我的程序中)或查找表(如在您的程序中)来处理缓冲区,无论哪种方法,您都需要进行一些调整。祝您好运。