vs2017 输出错误,但 mingw 有效
Posted
技术标签:
【中文标题】vs2017 输出错误,但 mingw 有效【英文标题】:wrong output by vs2017 but mingw works 【发布时间】:2017-06-22 07:03:48 【问题描述】:我写了一个简单的函数来从文件中加载一个 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;
【问题讨论】:
这里有一条注释说ftell
with files open in text mode 报告位置不正确:msdn.microsoft.com/en-us/library/0ys3hc0b.aspx
也许是对的,添加了一个可行的解决方案
这只是 vs 的 ftell 报告错误,我的意思是 gcc 的版本有效
【参考方案1】:
您不能便携地使用fseek()
/ftell()
来获取文件的大小。
根据the C Standard,脚注 268,第 301 页:
将文件位置指示器设置为文件结尾,与
fseek(file, 0, SEEK_END)
,对二进制文件有未定义的行为 流...
和
7.21.9.2
fseek
函数...二进制流不需要有意义地支持
fseek
调用whence
的值为SEEK_END
。
所以你不能可靠地使用fseek()
来到达二进制文件的末尾。事实上,C 标准明确将这样做定义为未定义的行为。
好的,所以您可以使用fseek()
到达以text 模式打开的文件的末尾,但是
7.21.9.4
ftell
函数...
对于文本流,其文件位置指示符包含未指定 信息,可由
fseek
函数用于返回文件 流的位置指示器到其当时的位置ftell
通话;两个这样的回报之间的差异 值不一定是对数量的有意义的度量 写入或读取的字符。
在文本文件中,ftell()
不会返回对获取文件大小有用的值。
简而言之,使用fseek()
/ftell()
来获取文件的大小从根本上被破坏了。它有时工作的事实只是一个实现细节。
【讨论】:
它是否可能会在某个时候报告得更少或者它过于执行细节?因为那样我使用的解决方案就会中断。 @bluedragon C 没有标准化的“文件”概念,因此任何解决方案都必须是特定于平台的。对于Windows,我认为GetFileSize( fileno( file ) );
应该可以工作,尽管GetFileSizeEx()
可能更好,而struct stat sb; fstat( fileno( file ) &sb );
可以在POSIX 系统上工作。在 Windows 和 POSIX 系统上,binary 流上的 fseek()
/ftell()
确实有效,但大小限制为签名的 long
值,或在 Windows 上为 2 GB。您可以使用ftello()
获取off_t
值,对于 64 位所有架构,该值应为 64 位。
寻找 EOF 的循环是否适用于正确的 ftell()以上是关于vs2017 输出错误,但 mingw 有效的主要内容,如果未能解决你的问题,请参考以下文章
解析器错误消息:文件“/TestSite/Default.aspx.cs”不存在
为什么Qt的libstdc ++版本 - 6.dll有效,但不是MinGW?
VS2017中使用ObjectARX 2019 wizard的 ArxWizMFCSupport向导出现的bug修复前因后果