【问题标题】:when using freopen() in visual studio c++ system("pause") is not working在 Visual Studio C++ 系统(“暂停”)中使用 freopen() 时不起作用
【发布时间】:2018-03-12 06:31:33
【问题描述】:

我试图从 vs17 中的文件中读取。但是这里 system("pause") 不起作用。这里的控制台窗口只是弹出并消失。 input.txt 文件只包含一个整数。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#pragma warning(disable:4996)
using namespace std;
int main()
{
    freopen("input.txt", "r", stdin);
    int n;
    cin >> n;
    cout << n << endl;
    system("pause");
   return 0;
}

那么有什么方法可以从文件中读取并在控制台中显示输出,直到给出来自键盘的另一个输入。提前致谢

【问题讨论】:

  • 试试system( "PAUSE" );
  • 和以前一样。
  • 在某个终端(在您的 IDE 之外)运行您的程序
  • 使用freopen 重新指向stdin 会限制您通过键盘从用户那里获取更多输入的选项。
  • freopen 会这样做,并且没有简单的方法可以恢复。为什么不使用std::ifstream fin("input.txt"); 和后来的fin &gt;&gt; n;

标签: c++ visual-c++ freopen


【解决方案1】:

你要么别惹stdin使用system("pause"),要么使用后恢复。

方法一:不要乱搞stdin

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include <fstream> // Include this
#pragma warning(disable:4996)
using namespace std;
int main()
{
    std::ifstream fin("input.txt");  // Open like this
    int n;
    fin >> n;  // cin -> fin
    cout << n << endl;
    system("pause");
   return 0;
}

使用单独的流来读取文件使控制台读取保持隔离。

方法二:恢复stdin

#include <io.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <iostream>

using std::cin;
using std::cout;

int main( void )  
{  
   int old;  
   FILE *DataFile;  

   old = _dup( 0 );   // "old" now refers to "stdin"   
                      // Note:  file descriptor 0 == "stdin"   
   if( old == -1 )  
   {  
      perror( "_dup( 1 ) failure" );  
      exit( 1 );  
   }  

   if( fopen_s( &DataFile, "input.txt", "r" ) != 0 )  
   {  
      puts( "Can't open file 'data'\n" );  
      exit( 1 );  
   }  

   // stdin now refers to file "data"   
   if( -1 == _dup2( _fileno( DataFile ), 0 ) )  
   {  
      perror( "Can't _dup2 stdin" );  
      exit( 1 );  
   }  
   int n;
   cin >> n;
   cout << n << std::endl;

   _flushall();  
   fclose( DataFile );  

   // Restore original stdin 
   _dup2( old, 0 );  
   _flushall();  
   system( "pause" );  
}

在这里您恢复原始stdin,以便system("pause") 可以使用控制台输入。将其分解为 2 个单独的函数 override_stdinrestore_stdin 可以更易于管理。

方法3:不要使用system("pause")

您可以(可选地使用 MSVC 提供的cl 命令行编译工具在控制台编译您的测试程序并)在命令行上运行程序,这样程序退出时就不会丢失输出。或者你可以搜索一些 IDE 选项来保持控制台监视输出,或者你可以在最后一行放置一个断点。 (可能是return 0),这可能有其自身的后果/问题。

【讨论】:

    【解决方案2】:

    关于system("pause");的信息

    至于system("Pause") 及其用途:我不建议在任何旨在移植或分发的代码库中使用它,原因如下:Why is it wrong!

    现在,如果您将它用于自己的快速肮脏黑客攻击以保持 Windows 控制台打开只是为了测试小函数或类,这很好,但是这里有一个替代方案,它可以做同样的事情,既符合标准又被便携。

    #include <iostream>
    #include <string>
    
    int main() {        
        [code...]
    
        std::cout << "\nPress any key to quit.\n";
        std::cin.get(); // better than declaring a char.
        return 0;
    }
    

    关于freopen()的信息

    要注意的另一件事是,您正在对文本文件调用freopen(),但在完成文件后,您永远不会有任何关闭文件的调用;我不知道freopen() 是否会自动为您执行此操作,但如果没有,那么您应该在退出程序之前以及从中提取所有需要的信息之后关闭文件句柄。

    这是一个相关的 Q/A stack: freopen()

    有关freopen()的更多信息,这里是一个优秀的资源网页:C: &lt;cstdio&gt; - freopen() & C++: &lt;cstdio&gt; - std::freopen()


    我尝试运行您的代码。

    现在我可以测试你的程序了。如果您使用 Visual Studio 并在调试模式下从调试器运行应用程序,它会在完成后自动关闭应用程序。您可以在不使用调试器 (ctrl + F5) 的情况下运行它,也可以从 IDE 外部的控制台或终端从生成的可执行文件的路径运行它,程序将以您期望的方式运行。

    【讨论】:

    • @user4581301 我正在搜索中
    • 您可以简单地使用std::cin.get(); 而不是声明char
    • @Tas 那是真的
    • AFAIK,“暂停”不区分大小写,因为 Windows 不区分大小写。例如在您的命令窗口中,“Start nOtEpAD”与“start notepad”相同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多