[英]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] = '\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;
}
您无法使用fseek()
/ ftell()
来获取文件的大小。
根据C标准 ,脚注268,第301页:
将文件位置指示器设置为文件结尾,与
fseek(file, 0, SEEK_END)
,具有二进制流的未定义行为...
和
7.21.9.2
fseek
功能...二进制流不一定有意义支持
fseek
用电话whence
的价值SEEK_END
。
因此,您无法可靠地使用fseek()
来到达二进制文件的末尾。 实际上,C标准明确规定这样做是不明确的行为。
好的,所以你可以使用fseek()
来到文本模式下打开的文件的末尾,但是
7.21.9.4
ftell
功能...
对于文本流,其文件位置指示符包含未指定的信息,
fseek
函数可使用该信息将流的文件位置指示符返回到ftell
调用时的位置; 两个这样的返回值之间的差异不一定是写入或读取的字符数的有意义的度量。
在文本文件中, ftell()
不返回在获取文件大小时有用的值。
简而言之,使用fseek()
/ ftell()
来获取文件的大小从根本上被打破。 它有时工作的事实只是一个实现细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.