vs2017的输出错误但mingw有效

时间:2017-06-22 07:03:48

标签: c++ file gcc mingw visual-studio-2017

我编写了一个简单的函数来从文件中加载一个char *缓冲区,但是当通过vs2017编译时,它会在缓冲区的末尾添加垃圾,但是mingw编译的exe会给出正确的输出 该功能看起来像是什么

#include <stdio.h>
#include <stdlib.h>

using namespace std;

char * loadfromfile(const char * _Filename)
{
    char * buffer;
    FILE * file = fopen(_Filename, "r");
    if (!file)
        return nullptr;
    fseek(file, 0, SEEK_END);
    auto _length = ftell(file);
    buffer = new char[_length + 1];
    rewind(file);
    printf("characters read(loadformfile()) :%i\n",fread(buffer, sizeof(char), _length, file));
    buffer[_length] = '\0';
    fclose(file);
    return buffer;
}

int main() {
    char * str = loadfromfile("D:\\shutdown.bat");
    printf("%s\n", (str) ? str : "failed to load");
    delete[] str;
    return 0;
}

VS2017输出:

characters read(loadformfile()) :86
@echo off
Set minutes=30
set /a seconds=%minutes%*60
TIMEOUT /T %seconds%
shutdown /s
\inst 

g ++(x86_64-posix-seh-rev0,由MinGW-W64项目构建)7.1.0输出:

characters read(loadformfile()) :zu
@echo off
Set minutes=30
set /a seconds=%minutes%*60
TIMEOUT /T %seconds%
shutdown /s

文件是:

@echo off
Set minutes=30
set /a seconds=%minutes%*60
TIMEOUT /T %seconds%
shutdown /s

修改

A working solution 
char * loadfromfile(const char * _Filename)
{
    char * buffer;
    FILE * file = fopen(_Filename, "r");
    if (!file)
        return nullptr;
    fseek(file, 0, SEEK_END);
    auto _length = ftell(file);
    buffer = new char[_length + 1];
    rewind(file);
    buffer[fread(buffer, sizeof(char), _length, file)] = '\0';
    fclose(file);
    return buffer;
}

1 个答案:

答案 0 :(得分:0)

您无法轻松使用fseek() / ftell()来获取文件的大小。

Per the C Standard,脚注268,第301页:

  

将文件位置指示器设置为文件结尾,如同   fseek(file, 0, SEEK_END),具有二进制文件的未定义行为   流...

  

7.21.9.2 fseek功能

     

...二进制流无需支持fseek调用   whence的{​​{1}}值。

因此,您无法可靠地使用SEEK_END来结束二进制文件。事实上,这样做是因为C标准明确指出是未定义的行为。

好的,您可以使用fseek()到达以文本模式打开的文件的末尾,但

  

7.21.9.4 fseek()功能

     

...

     

对于文本流,其文件位置指示符包含未指定   ftell函数可用于返回文件的信息   流的位置指示器到当时的位置   fseek电话;两次这样的回归之间的区别   价值不一定是数量的有意义的衡量标准   写的或读过的字符。

在文本文件中,ftell不会返回有助于获取文件大小的值。

简而言之,使用ftell() / fseek()来获取文件的大小从根本上被打破了。它有效 的事实只是一个实现细节。