2013-09-16 230 views
3

我想從二進制文件中計數零和一個數字。問題是,我得到了正確的答覆。的零,但一些出來等於沒有。的零。 我正在做的是通過char讀取char文件。由於可以有最多256個字符,我將結果存儲在零和一個臨時數組中,並且如果再次出現字符,則從那裏檢索結果。從二進制文件讀取

#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); 

} 
+12

你的問題的第二句話表明你根本沒有任何問題。 –

+0

你期望'c'能拿出什麼樣的價值? – Beta

+3

*「沒有人出來等於沒有人」*你在說什麼? – abelenky

回答

1

計數的零和做

c >>= 1; 

畢竟8個移位完成,c總是零破壞的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]; 
} 
+0

tnx fr指向...但仍然得到相同的問題 – Anshul

+0

@ user2733715你可以用代碼更新編輯問題嗎? – dasblinkenlight

0

如果你的目標只是在一個文件中按位計數10位,您可以使用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; 
} 

一個好的編譯器應該擴展中間循環,如果你通過它正確的優化標誌。

+0

@Sebastian Redl ..文件大小可能很大......因此無法避免查找表格會避免重新計算。 – Anshul

+0

@Anshul如果速度是你關心的問題,那麼我會建議(首先爲了清楚起見)用C++讀取文件命令替換C讀取文件命令,並將文件內容加載到緩衝區中。您目前按字符閱讀文件的方法可能會很慢。 – ilent2

+0

@Anshul對於256字節的隨機數據,我測量了兩個程序執行1000次的執行時間(對程序進行一些小的調整以使其可用)。你的程序耗時1.7秒,而我的耗時1.8秒,這是非常可比的,特別是考慮到我寫我的時候沒有考慮到優化。我的程序的附加優點是我可以給它一個10GB的文件,它仍然會運行,你需要進一步調整,如果你打算將整個文件內容存儲在內存中,你的程序可能無法運行。無論如何......專注於編寫易於閱讀的代碼,優化後者。 – ilent2