我编写了一个简单的函数来从文件中加载一个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;
}
答案 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()
来获取文件的大小从根本上被打破了。它有效 的事实只是一个实现细节。