vs2017 输出错误但 mingw 有效
wrong output by vs2017 but mingw works
我写了一个简单的函数来从文件加载 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] = '[=10=]';
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)] = '[=14=]';
fclose(file);
return buffer;
}
您不能便携地使用 fseek()
/ftell()
来获取文件的大小。
根据 the C Standard,脚注 268,第 301 页:
Setting the file position indicator to end-of-file, as with
fseek(file, 0, SEEK_END)
, has undefined behavior for a binary
stream ...
和
7.21.9.2 The fseek
function
... A binary stream need not meaningfully support fseek
calls with a
whence
value of SEEK_END
.
所以您不能可靠地使用 fseek()
到达二进制文件的末尾。实际上,C 标准特别 声明这样做是未定义的行为。
好的,所以您可以使用 fseek()
到达以 text 模式打开的文件的末尾,但是
7.21.9.4 The ftell
function
...
For a text stream, its file position indicator contains unspecified
information, usable by the fseek
function for returning the file
position indicator for the stream to its position at the time
of the ftell
call; the difference between two such return
values is not necessarily a meaningful measure of the number of
characters written or read.
在文本文件上,ftell()
没有 return 一个对获取文件大小有用的值。
简而言之,使用fseek()
/ftell()
来获取文件的大小从根本上是错误的。它 有时 起作用的事实只是一个实现细节。
我写了一个简单的函数来从文件加载 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] = '[=10=]';
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)] = '[=14=]';
fclose(file);
return buffer;
}
您不能便携地使用 fseek()
/ftell()
来获取文件的大小。
根据 the C Standard,脚注 268,第 301 页:
Setting the file position indicator to end-of-file, as with
fseek(file, 0, SEEK_END)
, has undefined behavior for a binary stream ...
和
7.21.9.2 The
fseek
function... A binary stream need not meaningfully support
fseek
calls with awhence
value ofSEEK_END
.
所以您不能可靠地使用 fseek()
到达二进制文件的末尾。实际上,C 标准特别 声明这样做是未定义的行为。
好的,所以您可以使用 fseek()
到达以 text 模式打开的文件的末尾,但是
7.21.9.4 The
ftell
function...
For a text stream, its file position indicator contains unspecified information, usable by the
fseek
function for returning the file position indicator for the stream to its position at the time of theftell
call; the difference between two such return values is not necessarily a meaningful measure of the number of characters written or read.
在文本文件上,ftell()
没有 return 一个对获取文件大小有用的值。
简而言之,使用fseek()
/ftell()
来获取文件的大小从根本上是错误的。它 有时 起作用的事实只是一个实现细节。