簡體   English   中英

使用ifstream時,Visual Studio 2017中Release和Debug的輸出不同?

[英]Output of Release and Debug are different in Visual Studio 2017 when using ifstream?

我嘗試編寫一個用於壓縮文件的程序,但是每次運行該程序時,都會得到不同的輸出。 當我調試該程序時,我發現std :: ifstream在Release和Debug之間將得到不同的結果。 這是我的程序:

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream inputfile("testing_file.txt");

    inputfile.seekg(0, ios::end);

    unsigned long filesize = inputfile.tellg();

    inputfile.seekg(0, ios::beg);

    char* buffer = new char[filesize];

    inputfile.read(buffer, filesize);

    for (int i = 0; i < filesize; ++i) {
        cout << (int)*(buffer + i) << endl;
    }

    delete[] buffer;
    inputfile.close();

    cin.get();

    return 0;
}

這是testing_file.txt:

for test !

我在使用Release模式時得到這個:

102
111
114
32
116
101
115
116
32
33
10
0

但是我在調​​試模式下得到了這個:

102
111
114
32
116
101
115
116
32
33
10
-51

所以我問為什么在同一個程序中會得到兩個不同的輸出。

對不起,我的英語不好。

對於調試版本,緩沖區所指向的內存被神奇地填充為0xCD ,而在發行版本中則沒有。 另外,為什么在代碼中需要手動進行內存管理? 請改用std::vector

它也對在塊末尾.close()文件無用,因為*fstream的析構函數無論如何都會為您完成。 RAII很棒。

您還應該注意的另一件事是,對於以文本模式打開的文件(換行符可能為'\\n'"\\r\\n" ),以這種方式查找文件大小將無法可靠地工作。

inputfile.seekg(0, ios::end);
unsigned long filesize = inputfile.tellg();

將占'\\r'inputfile.read(buffer, filesize); 將不會。

沒有胡扯的代碼:

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <cstdlib>

int main()
{
    char const * const filename{ "testing_file.txt" };
    std::ifstream inputfile{ filename };

    if (!inputfile) {
        std::cerr << "Error opening file \"" << filename << "\"!\n\n";
        return EXIT_FAILURE;
    }

    inputfile >> std::noskipws;
    std::vector<char> buffer{ std::istream_iterator<char>(inputfile), std::istream_iterator<char>() };

    for (auto & ch : buffer)
        std::cout << static_cast<int>(ch) << '\n';
}

關於為什么要首先打印多余的字節也值得一提。 您的程序嘗試確定文件大小,分配正確大小的緩沖區,讀取正確的字節數,然后僅打印那么多字節是正確的。

為什么要打印一個額外的字節(0或-53)?

如果將十六進制編輯器帶入文件,將看到十六進制值:

66 6f 72 20 74 65 73 74 20 21 0d 0a

注意最后的0d 0a 當您調用seekg() ,它將搜索到末尾,而tellg()的結果將為12。但是,該文件以文本模式打開,在Windows下這意味着0d 0a組合位於末尾該行減少為單個0a以保持與* nix處事方式的兼容性。

因此read()僅讀取11個字節,因此當您打印總共12個字節時,最后一個字節就是緩沖區中的內容。 @Swordfish的答案很好地說明了為什么零值相對於-53取決於構建。

請注意,當這些十六進制值轉換為十進制值時,它們與程序的輸出完全匹配,除了缺少0d之外,這是33與最后10之間的13。

如果以二進制模式打開文件,則該多余的字節將出現,更改后的字節將消失:現在,兩個構建都將產生相同的輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM