system() 搞砸了 \n\r\t
Screwing up \n\r\t by system()
我已经阅读并尝试了很多解决方案,但都没有解决我的问题。
我正在用 C++ 代码生成一个 dll,并希望在控制台 window 中显示 printf() 或 std::cout。为了测试,我只是从 C++ 代码中创建了一个 .exe,但这并没有解决问题![=13=]
我知道 system("Pause") 是个坏习惯,但这只是解决同样问题的简单方法。我没有调用 system("Pause"),而是在调用 cl.exe 并从 .c 文件中编译一个 dll(例如:system("cl.. .). 从另一个 c 文件生成 dll 没有任何问题。但是在我调用编译 dll 文件的系统函数之后,printf 和 std::out 没有在控制台中显示正确的文本 window.
这是我的示例代码,它搞砸了正确字符的显示:
#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;
}
这是输出的图片:
我在调用 system() 之前和之后尝试了 fflush。
下面是我的进一步想法:
- 我可以通过 CreateProcess 调用 cl.exe 吗?这会解决我的问题吗?如果可以,我将如何做到这一点并实现批量 vcvars32.bat 中的环境变量。所以我想从位于同一文件夹中的 .c 创建一个 dll。
- 或者可以编写一个批处理文件来调用整个 cl.exe 和 vcvars32.bat 文件处理过程。
- 或者是否有另一种方法来显示 dll 中的值而不是调用 AllocConsole()?
我希望你能帮助我,也许我遗漏了什么!
看起来该进程正在更改控制台上的输出代码页,然后在完成后没有改回来。不确定为什么会发生这种情况,但如果这是原因,那么保存和恢复代码页应该就足够了:
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()
。
因此,为了在我的笔记本电脑上尝试这些错误(因为我今天正在旅行),我在我的笔记本电脑上设置了相同的代码。因为我忘记取消选中 Security Development Lifecycle (SDL) checks
调用 freopen("CONOUT$", "w", stdout);
时出错。因为在 visual studio 2015 中构建代码时的错误消息是:
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
我搜索了函数 freopen_s 并在 freopen_s 的示例中进行了精确搜索 我看到了以下代码 Outputting Unicode to Allocated Console Issue:
freopen_s(&stream, "CONOUT$", "w+t", stdout);
我试了这个,结果我的问题终于解决了!但是解决问题的不是 freopen_s 它只是它的内部 "w+t"
所以我查了一下,发现 w+
指的是以下访问类型 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.
所以我尝试了一些组合并得到了这个结果:
wt
不工作
w+t
有效(但 t 始终是标准的,即使您使用 w+
与 w+t
相同
w+
工作
所以我想我只需要设置一个空文件来读写!我将进一步深入研究,因为我不太确定有什么区别,以及在使用 dll 而不是 exe 文件时它是否仍在解决问题!
希望这可以帮助其他一些试图解决同样错误的人!但是一个“+”现在耽误了我一天多的时间!
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!
我已经阅读并尝试了很多解决方案,但都没有解决我的问题。
我正在用 C++ 代码生成一个 dll,并希望在控制台 window 中显示 printf() 或 std::cout。为了测试,我只是从 C++ 代码中创建了一个 .exe,但这并没有解决问题![=13=]
我知道 system("Pause") 是个坏习惯,但这只是解决同样问题的简单方法。我没有调用 system("Pause"),而是在调用 cl.exe 并从 .c 文件中编译一个 dll(例如:system("cl.. .). 从另一个 c 文件生成 dll 没有任何问题。但是在我调用编译 dll 文件的系统函数之后,printf 和 std::out 没有在控制台中显示正确的文本 window.
这是我的示例代码,它搞砸了正确字符的显示:
#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;
}
这是输出的图片:
我在调用 system() 之前和之后尝试了 fflush。
下面是我的进一步想法:
- 我可以通过 CreateProcess 调用 cl.exe 吗?这会解决我的问题吗?如果可以,我将如何做到这一点并实现批量 vcvars32.bat 中的环境变量。所以我想从位于同一文件夹中的 .c 创建一个 dll。
- 或者可以编写一个批处理文件来调用整个 cl.exe 和 vcvars32.bat 文件处理过程。
- 或者是否有另一种方法来显示 dll 中的值而不是调用 AllocConsole()?
我希望你能帮助我,也许我遗漏了什么!
看起来该进程正在更改控制台上的输出代码页,然后在完成后没有改回来。不确定为什么会发生这种情况,但如果这是原因,那么保存和恢复代码页应该就足够了:
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()
。
因此,为了在我的笔记本电脑上尝试这些错误(因为我今天正在旅行),我在我的笔记本电脑上设置了相同的代码。因为我忘记取消选中 Security Development Lifecycle (SDL) checks
调用 freopen("CONOUT$", "w", stdout);
时出错。因为在 visual studio 2015 中构建代码时的错误消息是:
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
我搜索了函数 freopen_s 并在 freopen_s 的示例中进行了精确搜索 我看到了以下代码 Outputting Unicode to Allocated Console Issue:
freopen_s(&stream, "CONOUT$", "w+t", stdout);
我试了这个,结果我的问题终于解决了!但是解决问题的不是 freopen_s 它只是它的内部 "w+t"
所以我查了一下,发现 w+
指的是以下访问类型 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.
所以我尝试了一些组合并得到了这个结果:
wt
不工作w+t
有效(但 t 始终是标准的,即使您使用w+
与w+t
相同
w+
工作
所以我想我只需要设置一个空文件来读写!我将进一步深入研究,因为我不太确定有什么区别,以及在使用 dll 而不是 exe 文件时它是否仍在解决问题! 希望这可以帮助其他一些试图解决同样错误的人!但是一个“+”现在耽误了我一天多的时间!
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!