2017-08-08 121 views
1

我想將std::cerrstd::cout的輸出重定向到文件。爲此,我使用了以下代碼示例中的rdbuf函數。不幸的是,我收到異常嘗試將std :: cerr重定向到文件時出現訪問衝突異常

Exception thrown: read access violation. 

*(__imp_std::basic_ios<char,std::char_traits<char> >::rdbuf(...)) was 0xCCCCCCCC. 

每當我試着寫什麼std::coutstd::cerr

這裏是產生我的問題代碼示例:

void redirect() 
{ 
    auto t = std::time(nullptr); 
    auto tm = *std::localtime(&t); 

    std::ostringstream oss; 
    oss << std::put_time(&tm, "%Y-%m-%d_%H-%M-%S.log"); 
    auto cerrFileName = "cerr-" + oss.str(); 
    auto coutFileName = "cout-" + oss.str(); 


    std::ofstream cerrFile(cerrFileName, std::ios::ate); // file is created 
    std::cerr.rdbuf(cerrFile.rdbuf()); 

    std::ofstream coutFile(coutFileName, std::ios::ate); // file is created 
    std::cout.rdbuf(coutFile.rdbuf()); 
} 

int main() 
{ 
    redirect(); 

    std::cout << "Test"; // The exception is thrown here. 

    return 0; 
} 

此示例創建兩個文件,因爲它應該,但不寫任何東西到他們既不。我究竟做錯了什麼?

+1

考慮您將輸出重定向到的對象的生命週期。 – molbdnilo

回答

3

std::ofstream擁有自己的緩衝區,std::ofstream對象超出範圍,他們破壞了緩衝區,導致std::coutstd::cerr使用無效的指針指向緩衝區。

確保緩衝區不被過早刪除。

+0

新人的錯誤。謝謝您的幫助。 – MxNx

+1

@MxNx錯誤是通向專業知識的唯一途徑! –

2

用例如

std::cout.rdbuf(coutFile.rdbuf()); 

你讓std::cout份額相同緩衝區coutFile,你只設置指針

不幸的是std::basic_streambuf未被引用計數。這意味着當redirect函數返回時,coutFile被破壞並關閉,其中包括破壞緩衝區對象。

例如, std::cout帶有一個指向不存在的緩衝區對象的指針。

您共享緩衝區對象的流需要在整個程序上有一個生命週期。 在退出程序之前,您需要恢復原始緩衝區std::coutstd::cerrrdbuf返回指向舊緩衝區的指針)。

+0

這解決了這個問題。感謝您提供豐富的回覆。 – MxNx