读取文件的大小错误

时间:2014-08-08 08:26:58

标签: c++

分辨

我试图制作一个简单的文件加载器。 我的目标是将着色器文件(纯文本文件)中的文本转换为char *,我将在稍后编译。

我尝试过这个功能:

char* load_shader(char* pURL)
{
    FILE *shaderFile;
    char* pShader;

    // File opening
    fopen_s( &shaderFile, pURL, "r" );
    if ( shaderFile == NULL )
        return "FILE_ER";

    // File size
    fseek (shaderFile , 0 , SEEK_END);
    int lSize = ftell (shaderFile);
    rewind (shaderFile);

    // Allocating size to store the content
    pShader = (char*) malloc (sizeof(char) * lSize);
    if (pShader == NULL)
    {
        fputs ("Memory error", stderr); 
        return "MEM_ER";
    }

    // copy the file into the buffer:
    int result = fread (pShader, sizeof(char), lSize, shaderFile);
    if (result != lSize)
    {
        // size of file 106/113
        cout << "size of file " << result << "/" << lSize << endl;
        fputs ("Reading error", stderr);
        return "READ_ER";
    }

    // Terminate
    fclose (shaderFile);
    return 0;

}

但正如你在代码中看到的那样,我在进程结束时有一个奇怪的大小差异,这使我的函数崩溃。

我必须说我是C中的初学者,所以我可能错过了关于内存分配,类型,指针的一些细微差别...... 如何解决此尺寸问题?

* 编辑1:

首先,我不应该在结束时返回0但是pShader;这似乎是程序崩溃的原因。 然后,我将reult的类型更改为size_t,并将一个结束字符添加到pShader,添加pShdaer [result] =&#39; / 0&#39 ;;在声明后,我可以正确显示它。 最后,正如@JamesKanze建议的那样,我把fopen_s变成了fopen,因为之前在我的情况下没有用。

1 个答案:

答案 0 :(得分:0)

首先,对于这种原始访问,您可能会更好 使用系统级功能:CreateFileopenReadFileread以及CloseHandleclose GetFileSizestat来获取尺寸。使用FILE*std::filebuf只会引入额外的级别 缓冲和处理,在您的情况下无益。

至于您所看到的内容:无法保证ftell 将返回任何可利用的数字值;它可能 很好只是一个神奇的饼干。在大多数现有系统中,它 字节偏移到物理文件中,但在任何非Unix上 系统,物理文件的偏移量不会直接映射 到您正在阅读的逻辑文件,除非您打开该文件 二进制模式。如果您使用"rb"打开该文件,那么您就可以了 可能看到相同的值。 (从理论上讲,你可以得到 文件末尾的额外0,但实际上是操作系统 发生的事情要么已经灭绝,要么仅用于遗产 大型机。)

编辑:

由于答案说明已被删除:你应该循环 在fread上,直到它返回0(之前将errno设置为0 每次调用,并在返回后检查它是否有 由于错误或因为它到达而返回的函数 文件结束)。话虽如此:如果你是平常的话 Windows或Unix系统,该文件是机器本地的, 并且不会太大,fread将一次性读取所有内容。该 你看到的大小差异(给定数值 你发布的)几乎肯定是由于这两个事实 字节Windows行结尾被映射到单个'\n' 字符。为避免这种情况,您必须以二进制模式打开; 或者,如果你真的在处理文本(并希望 这个映射),你可以忽略你的额外字节 缓冲区,在最后一个字节后设置'\0'终止符 实际上读了。