繁体   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