简体   繁体   中英

Screwing up \n\r\t by system()

I have read and tried many solutions and nothing solved my problem.

I am generating a dll out of c++ code and want to display the printf() or the std::cout inside of a console window. For testing I just create a .exe out of the c++ code but that is not solving the problem!

I know that system("Pause") is a bad habit, but this is just an easy way to get the same problem. Instead of calling system("Pause") I'm doing a system()-call that is calling the cl.exe and is compiling a dll out of a .c file(Like: system("cl...). The generation of the dll out of the other c file is working without any problems. But after I called the system function for compiling the dll file the printf and std::out are not displaying the right text in the console window.

here is my example code that is screwing up the display of the right characters:

#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;
}

Here is a picture of the output:

输出std :: cout

I tried the fflush before and after calling the system().

So here are my further thoughts:

  • Could I call the cl.exe by a CreateProcess and would that solve my problem?And when yes, how will I do that and to implement the environment variables out of the batch vcvars32.bat. So I want to create a dll out of a .c located both in the same folder.
  • Or could write a batch file that is calling the whole cl.exe and vcvars32.bat file process.
  • Or is there another way to display the values out of a dll instead of calling AllocConsole()?

I hope you can help me maybe I'm missing something!

So in order to try these error on my laptop (because I'm travelling today) I set up the same code at my laptop. Because I forgot to uncheck Security Development Lifecycle (SDL) checks there was an error when calling freopen("CONOUT$", "w", stdout); .Because the error message at building the code inside of visual studio 2015 was:

Severity Code Description Project File Line Error C4996 'freopen': This function or variable may be unsafe. Consider using freopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ConsoleApplication1 c:\\users\\noxious\\documents\\visual studio 2015\\projects\\consoleapplication1\\consoleapplication1\\consoleapplication1.cpp 12

I searched for the function freopen_s and exact at a example of freopen_s I saw the following code Outputting Unicode to Allocated Console Issue :

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

I tried this one and acually my problem was solved! BUT it wasn't the freopen_s that solved the problem it was just the inside of it "w+t" so I looked it up and saw that w+ is refering to the following type of access cstdio: freopen :

"w+" Create an empty file for reading and writing. If a file with the same name already exists its content is erased before it is opened.

So I tried a few combinations and got this resulst:

  • wt not working
  • w+t working (but the t is always standard even if you use w+ is the same as w+t
  • w+ working

So I think I have just to setup an empty file for reading and writing! I will looking further deep into that because I'm not quite sure what is the difference and if it is still solving the problem when using the dll instead of the exe file! Hope this might help some other people who are trying to solve same errors! But just a "+" was delaying my work now for more than one day!

Edit 5.10.2015: So I tested this function with the "w+" instead of "w" and it fixed my problem!Even using a dll instead of a generated exe!

It looks like the process is changing the output codepage on the console, then not changing it back when it's done. Not sure why this would happen, but if that's the cause, it should be sufficient to save and restore the codepage:

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;

BTW, it might also be screwing up the input codepage. You can use GetConsoleCP() and SetConsoleCP() for that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM