[英]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.