在Linux中的Cout和Cin - 看不到控制台

3

我刚从Windows转到Linux,正在尝试创建一个简单的应用程序,打开控制台,显示一条消息并等待按键关闭。我已经在Windows上创建了它并且它可以正常工作,然后我只是将文件移到了Linux。没有做任何更改,只是使用g++编译它,没有出现错误。问题是在Linux(Ubuntu 12.04)上,我看不到控制台和一些消息要求我在关闭之前按任意键。我的代码就像这样简单:

#include <iostream>
#include <cstdio>

int main() {
    cout << "Writing file...\n";

        FILE *myfile = fopen("testfile.txt", "w");
        fwrite("test", sizeof(char), 4, myfile);
        fclose(myfile);

    cout << "Press any key to exit...\n";
    cin.ignore();
    return 0;
}

在Windows上,当我启动可执行文件时,控制台窗口会显示消息,并在按任意键后关闭。在Linux上,当我执行程序时,什么也没有出现。它确实创建了testfile.txt文件并插入了文本,因此cstdio相关函数确实可以工作,但我看不到任何具有这些消息的控制台,我不知道原因。也许我不知道如何在Linux上打开一个简单的可执行文件。我的目标是双击它并看到带有两个简单消息的控制台窗口。您认为我做错了什么?谢谢!
此外,我使用g ++编译cpp文件:g++ -Wall -s -O2 test.cpp -o test

2
你发布的代码连编译都过不了。但是如果它能编译通过,你会得到一个名为 test 的可执行文件,你可以在控制台中输入 ./test 来运行它,前提是你正处于该文件所在的目录中。 - juanchopanza
1
听起来你是从桌面 GUI 运行它的 - Linux 上有不止一种这样的 GUI,你可能需要指定哪一个(或者至少指定你正在使用的发行版)。 - John Carter
抱歉,我逐字逐句地输入了代码,可能插入了一些错误字符。但是代码可以编译通过,这不是问题。正如我所说的,fwrite有效,它创建了一个文本文件。我看不到的是控制台显示消息的内容。我不想使用终端来完成这个任务,我只想单击它并打开包含消息的控制台。 - ali
4个回答

8
在Windows上,“自然”的应用程序形式是GUI应用程序。当您运行控制台应用程序时,系统会创建一个窗口来运行控制台并在该窗口中运行应用程序。这是由Windows完成的,它不是C++的固有属性,也不是您编写的代码所暗示的。
C++不会自动执行此操作,类UNIX系统也不会为您执行此操作。
在类UNIX系统上,“自然”的应用程序类型是(可以争议)控制台应用程序,并且您通常会从控制台或终端中运行它们。
当您运行程序时,输出将发送到运行X11会话的终端,但您看不到它,因为X11会话正在控制您的显示器。
因此,要获得所需的行为,首先打开终端,然后运行程序。
要使程序在终端中运行,请尝试运行类似于xterm -e ./test的内容。
要自动执行此操作,您可以使用以下方法:
#include <iostream>
#include <string>
#include <unistd.h>
#include <cstdio>

int main(int argc, char** argv)
{
  if (argc > 1 && std::string(argv[1]) == "-xterm")
  {
    if (::execl("/usr/bin/xterm", "xterm", "-e", argv[0], (char*)NULL))
    {
      std::perror("execl");
      return 1;
    }
  }

  std::cout << "Writing file...\n";

  FILE* myfile = std::fopen("testfile.txt", "w");
  std::fwrite("test", sizeof(char), 4, myfile);
  std::fclose(myfile);

  std::cout << "Press any key to exit...\n";
  std::cin.get();
}

现在,如果你使用参数-xterm运行程序,它将在xterm中运行。
注意:我修复了你的非便携代码,使用了<cstdio>中的名称的std::限定。

不错的 exec 示例。不幸的是我不能再点赞了。 - juanchopanza

2

Windows系统打开控制台是因为只有这种方式才能使用stdio。Linux则不需要,因为在没有控制台的情况下它也可以正常工作(默认输出到X会话错误日志~/.xsession-errors)。如果您希望用户能够访问stdio,则需要先打开终端和shell,然后再在其中运行可执行文件。


我可以创建一个shell脚本来打开可执行文件,然后,我的意思是,将其变成一个点击即可打开的应用程序。 - ali
那样做没有帮助。同样的事情还会发生。相反,创建一个 .desktop 文件,在终端中运行它。 - Ignacio Vazquez-Abrams
我认为你是对的。所以,没有办法从可执行文件中打开终端,然后显示消息。如果我想要在屏幕上输出,我必须首先打开终端,然后从其中执行程序。假设这是Linux上的工作方式。 - ali
@ali,你可以使用forkexec来从你的程序中“生成”一个终端,然后进行其他操作。 - juanchopanza
2
@juanchopanza,不需要fork,只需使用exec来替换当前进程,以运行相同二进制文件的xterm。 - Jonathan Wakely
1
@juanchopanza,我已经更新了我的回答,并附上了一个这样做的示例。 - Jonathan Wakely

1

您还没有告诉您的桌面环境在终端窗口中运行该程序。您的程序也没有说明,它只是将输出写入其标准输出。

要查看程序的标准输出,最好打开控制台,并键入编译后的程序名称以运行它。程序的标准输出将显示在同一窗口中。


0

而不是

cin.ignore();

做一个

cin.get();

在编译目录中,使用终端窗口启动程序:
./test

然后它会在标准输出上写入“正在写入文件…”和“按任意键退出…”,您需要按任意键终止应用程序。


为什么要踩我?我进行了替换,因为这样进程就会停止,这样他就可以看到正在发生的事情,并且必须按任意键继续进程。 - Julien May

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接