簡體   English   中英

帶有讀取的隨機字節

[英]Random bytes with fread

#post

我的變量名不是很重要! 該代碼有效時將被刪除!

#post

好吧,所以我在stdio.h中使用fread讀取文本文件。 問題是,據我所知,我一直在讀取文本文件中不存在的隨機字節。 我假設它們是文件方案的一部分,但我只是想確保它不是我的代碼。

#include "stdafx.h"
#ifdef WIN32
    #include <io.h>
#else
    #include <sys/io.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

#include "n_script_timer.h"
//using namespace std;

#ifdef _INC_WCHAR
    typedef wchar_t CHR;
#else
    typedef char CHR;
#endif
int _tmain(int argc, CHR* argv[])
{
    #ifndef _DEBUG
        if(argc == 1)
        {
            printf("You must drag a file onto this program to run it.");
            scanf("%*c");
            return 0;
        }
        CHR* fname = argv[1];
    #else
        #ifdef _INC_WCHAR
            const CHR fname[16] = L"f:\\deleteme.bin";
        #else
            const CHR fname[16] = "f:\\deleteme.bin";
        #endif
    #endif

    FILE* inFile;
    long len;
    struct Script_Timer a;
    //static const int bsize = 4096*6;
    static const int bsize = 84;
    typedef CHR chhh[bsize];
    int alen;
    printf("#Opening File '%s' ...\n",fname);
    #ifdef _INC_WCHAR
        if((inFile = _wfopen(fname,L"rb")) == NULL)
    #else
        if((inFile = fopen(fname,"r")) == NULL)
    #endif
    {
        printf("Error opening file '%s' ",fname);
        return 0;
    }
    fseek(inFile,SEEK_SET,0);
    #ifdef _WIN32
        len = _filelength( inFile->_file );
    #else
        len = _filelength(inFile->_fileno);
    #endif
    printf("  !FileLength: %d\n",len);
    printf("#Creating Buffers...\n");
    if(((float)len/(float)bsize) > (len/bsize))
    {
        alen = (len/bsize) + 1;
    }
    else alen = (len/bsize);
    #ifdef WIN32
        //chhh *cha = new chhh[alen];
        chhh cha[alen];
    #else
        chhh cha[alen];
    #endif
    printf("#Reading File...\n");
    Start_ST(&a);
    int i = 0;
    for(i=0;i<alen;++i)
    {
        fread(&cha[i],sizeof(CHR),bsize,inFile);
        printf("[%i]%s",i,cha[i]);
    }
    End_ST(&a);
    fclose(inFile);
    printf("Characters per millisecond: %f \n",((float)len/a.milliseconds));
    printf("Characters per second: %f \n",((float)len/a.milliseconds) * 1000);
    scanf("%*c");
    return 0;
}

這里有一些奇怪的事情:

int i = 0;
for(i=0;i<alen;++i)
{
   fread(&cha[i],sizeof(CHR),bsize,inFile);
   printf("[%i]%s",i,cha[i]);
}
  1. 您不要在打印緩沖區之前將其終止為null(如RageZ所指出的那樣)。

  2. 您在每次循環重復中都增加i ,但是每次您將84個字符( bsize )讀入&cha[i] 我認為這應該意味着您只會看到第84個角色。

另外,如果我是你,我將每次檢查fread的返回值。 不能保證總是返回您期望的字節數。


編輯:您正在讀取的塊的大小很好。 我對typedef感到困惑。 每次將i遞增1時,指針便會按您的預期前進84*sizeof(CHR) 不過,您不能保證它會讀取您認為已讀取的字節數。 如果不是很短,則緩沖區中將留有垃圾:說它讀了60個字符,在下一次讀取的插入點之前留下了24個垃圾字符。

cha緩沖區應該在之前填充為null (0),否則您將獲得一些垃圾。

printf("[%i]%s",i,cha[i]);

就像printf一直輸出到屏幕,直到遇到NULL為止,因此在最佳情況下,您將有一些垃圾,最糟糕的是會發生某些訪問沖突,因為您訪問的是您不擁有的內存。

注意 :我建議您給變量/ typedef等賦予有意義的名稱,例如chhh並不是很好。 即使您修改這樣的代碼,幾個月后也將很痛苦!

typedef CHR chhh[bsize];

fread(&cha[i], sizeof(CHR), bsize, inFile);

在C ++中,字符串末尾的'\\ 0'需要一個額外的字節。

請注意,如果使用wchar_t代碼路徑,則alen計算將是錯誤的,因為bsize是數組的元素計數,而不是其大小(以字節為單位)。

我建議您嘗試更改變量名以准確描述它們的含義,如果發現錯誤,您會發現發現錯誤要容易得多。

您可能還存在緩沖區溢出錯誤。

int i = 0;
for(i=0;i {
fread(&cha[i],sizeof(CHR),bsize,inFile);
printf("[%i]%s",i,cha[i]);
}

In the above loop, you are reading a quantity of bsize at each position in the cha array. Unless bsize is one, you will have buffer overflow problems and the data in the array will not match the data in the file. With Unicode, I don't think you can use binary I/O. Because Unicode uses more than one byte for representing characters, you run into byte ordering issues (Big Endian vs. Little Endian). If your machine architecture has the same Endianess as the Unicode specification, you will have no problems. But if the program is run on a different architecture...

In the above loop, you are reading a quantity of bsize at each position in the cha array. Unless bsize is one, you will have buffer overflow problems and the data in the array will not match the data in the file. With Unicode, I don't think you can use binary I/O. Because Unicode uses more than one byte for representing characters, you run into byte ordering issues (Big Endian vs. Little Endian). If your machine architecture has the same Endianess as the Unicode specification, you will have no problems. But if the program is run on a different architecture...

As others have stated, don't develop specific code to handle the switching between Unicode and ASCII (8-bit). Look in the compiler manual and use methods that will operate on either Unicode or ASCII, depending on the compiler switch. Only write new code when the compiler or OS doesn't have the functionality you need. In this case, you need an that will operate on either; but definitely not fread that will operate on either; but definitely not fread . As others have stated, don't develop specific code to handle the switching between Unicode and ASCII (8-bit). Look in the compiler manual and use methods that will operate on either Unicode or ASCII, depending on the compiler switch. Only write new code when the compiler or OS doesn't have the functionality you need. In this case, you need an that will operate on either; but definitely not fread

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM