簡體   English   中英

通過系統()擰緊\\ n \\ r \\ n

[英]Screwing up \n\r\t by system()

我已閱讀並嘗試了許多解決方案,但沒有解決我的問題。

我正在用c ++代碼生成一個DLL,並希望在控制台窗口中顯示printf()或std :: cout。 為了測試我只是從c ++代碼創建一個.exe但是沒有解決問題!

我知道系統(“暫停”)是一個壞習慣,但這只是解決同樣問題的一種簡單方法。 而不是調用系統(“暫停”)我正在做一個系統() - 調用cl.exe並正在編譯一個.c文件的dll(如:system(“cl ...)”。)從其他c文件生成的dll工作沒有任何問題。但是在我調用系統函數來編譯dll文件之后,printf和std :: out沒有在控制台窗口中顯示正確的文本。

這是我的示例代碼,它搞砸了正確字符的顯示:

#include "stdafx.h"
#include <iostream>
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    AllocConsole();
    freopen("CONOUT$", "w", stdout); 
    std::cout << "Everything works fine\n";
    // Calling the cl.exe by cmd...
    system("Pause");
    std::cout << "now its strewd up the newline is not working\n" << std::endl;
    FreeConsole();
    return 0;
}

這是輸出的圖片:

輸出std :: cout

我在調用system()之前和之后嘗試了fflush。

所以這是我的進一步想法:

  • 我可以通過CreateProcess調用cl.exe並解決我的問題嗎?如果是,我將如何做到這一點並從批處理vcvars32.bat中實現環境變量。 所以我想創建一個位於同一文件夾中的.c的dll。
  • 或者可以寫一個調用整個cl.exe和vcvars32.bat文件進程的批處理文件。
  • 或者是否有另一種方法來顯示dll中的值而不是調用AllocConsole()?

我希望你能幫助我,也許我錯過了什么!

因此,為了在我的筆記本電腦上嘗試這些錯誤(因為我今天正在旅行),我在筆記本電腦上設置了相同的代碼。 因為我忘記取消選中Security Development Lifecycle (SDL) checks所以在調用freopen("CONOUT$", "w", stdout);時出錯freopen("CONOUT$", "w", stdout); 。因為構建visual studio 2015內部代碼的錯誤消息是:

嚴重性代碼說明項目文件行錯誤C4996'freopen':此函數或變量可能不安全。 請考慮使用freopen_s。 要禁用棄用,請使用_CRT_SECURE_NO_WARNINGS。 詳細信息請參見在線幫助。 ConsoleApplication1 c:\\ users \\ noxious \\ documents \\ visual studio 2015 \\ projects \\ consoleapplication1 \\ consoleapplication1 \\ consoleapplication1.cpp 12

我在freopen_s的一個例子中搜索了函數freopen_s和exact我看到以下代碼將Unicode輸出到Allocated Console問題

freopen_s(&stream, "CONOUT$", "w+t", stdout);

我試過這個,我的問題解決了! 但是不是freopen_s解決了問題,它只是它內部的"w+t"所以我查了一下,看到w+引用了以下類型的訪問cstdio:freopen

“w +”創建一個空文件進行讀寫。 如果已存在具有相同名稱的文件,則其內容在打開之前將被刪除。

所以我嘗試了幾種組合並得到了這個結果:

  • wt不工作
  • w+t工作(但即使你使用w+ ,t總是標准的,與w+t相同
  • w+工作

所以我想我只需要設置一個空文件進行讀寫! 我將進一步深入研究,因為我不太確定有什么區別,如果在使用dll而不是exe文件時它仍在解決問題! 希望這可能會幫助其他試圖解決相同錯誤的人! 但只是一個“+”現在推遲了我的工作超過一天!

編輯5.10.2015:所以我用“w +”而不是“w”測試了這個函數,它解決了我的問題!即使使用dll而不是生成的exe!

看起來該過程正在改變控制台上的輸出代碼頁,然后在完成后不再更改它。 不知道為什么會發生這種情況,但如果這是原因,那么保存和恢復代碼頁就足夠了:

AllocConsole();
freopen("CONOUT$", "w", stdout); 
std::cout << "Everything works fine\n";
// Calling the cl.exe by cmd...
UINT codepage = GetConsoleOutputCP();
system("Pause");
SetConsoleOutputCP(codepage);
std::cout << "Should work now." << std::endl;
FreeConsole();
return 0;

順便說一下,它也可能搞砸輸入代碼頁。 您可以使用GetConsoleCP()SetConsoleCP()

暫無
暫無

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

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