带有fread的随机字节

时间:2009-12-05 03:45:31

标签: c++ winapi

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

5 个答案:

答案 0 :(得分:7)

这里有几件奇怪的事情:

int i = 0;
for(i=0;i<alen;++i)
{
   fread(&cha[i],sizeof(CHR),bsize,inFile);
   printf("[%i]%s",i,cha[i]);
}
  1. 在打印缓冲区之前,不要将其终止(如RageZ指出的那样)。

  2. 您在每次循环重复时递增i,但每次将{84 {chars(bsize)读取到&cha[i]时。我认为这应该意味着你只看到每个第84个角色。

  3. 另外,如果我是你,我每次都会检查fread的返回值。不能保证始终返回您期望的字节数。


    编辑:您正在阅读的块的大小很好。我被typedef弄糊涂了一分钟。每次将i递增1时,它会按指定的方式将指针前移84*sizeof(CHR)。但是,您无法保证它会读取您认为它所执行的字节数。如果它变短了那么你将在缓冲区中留下垃圾:说它读取60个字符,在下一次读取的插入点之前留下24个垃圾字符。

答案 1 :(得分:2)

cha缓冲区之前应填充null(0),否则你会得到一些垃圾。

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

就像printf输出到屏幕直到遇到NULL一样,所以在最好的情况下你会有一些垃圾,最糟糕的是一些访问冲突,因为你访问了你不拥有的内存。

注意:我建议你给你的变量/ typedef等提供有意义的名字,比如chhh并不是很好。即使您修改此类代码,在几个月内也会很痛苦!

答案 2 :(得分:2)

typedef CHR chhh[bsize];

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

在C ++中,字符串末尾的'\ 0'需要一个额外的字节。

答案 3 :(得分:2)

请注意,如果您使用wchar_t代码路径,那么您的alen计算将会出错,因为bsize是数组的元素数,而不是字节数。

我建议您尝试更改变量名称以准确描述它们的含义,如果您这样做,您会发现更容易发现错误。

答案 4 :(得分:0)

您可能还有缓冲区溢出错误。

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

}