C++文件重定向

16

为了加快输入速度,我看到你可以使用文件重定向并包含一个已经设置好cin输入的文件。

理论上它应该像以下这样使用:

App.exe inputfile outputfile
据我理解C++ Primer书籍所述,以下C++代码[1]应该从文本文件中读取cin输入,并且不需要其他特殊的指示[2]。
[2]
include <fstream>
ofstream myfile;
myfile.open ();

[1] 以下是 C++ 代码...

#include <iostream>
int main()
{
    int val;
    std::cin >> val; //this value should be read automatically for inputfile
    std::cout << val;
    return 0;
}

我有什么遗漏吗?


1
是的 - 这不是它应该被使用的方式。 - Lightness Races in Orbit
4个回答

22

要使用您的代码[1],您必须像这样调用您的程序:

App.exe < inputfile > outputfile

您也可以使用:

App.exe < inputfile >> outputfile
在这种情况下,输出不会在每次运行命令时被重写,而是会附加到已经存在的文件中。
有关在Windows中重定向输入和输出的更多信息,您可以在此处找到。
请注意,<>>>符号应该要按照原样输入,它们在本说明中不仅仅是用于演示的目的。例如:
App.exe < file1 >> file2

5
您也可以使用 App.exe < inputfile >> outputfile。注意多出来的'>'符号。这种方法将新输出追加到文件末尾,而不是覆盖掉之前的内容。 - Kelm
1
谢谢@gawi,我以为<和>用来表示变量或其他什么东西。 - zurfyx
@Jerry 不用谢,顺便提一下,如果你想更快地运行程序,可以使用 printf/scanf 函数。或者,如果你真的想加快读写数据的速度,则可以使用 fgets/puts 函数(但是这样做必须知道自己在做什么 :)) - gawi
@gawi 现在还在胡说八道地说 printf/scanfcin/cout 更快,但至少语法是正确的。 - Bartek Banachewicz
@BartekBanachewicz,你认为cin/cout在执行时间上与scanf/printf相当吗?也许最近有所改进,但在过去,即使禁用了同步:std::ios_base::sync_with_stdio(false); 流仍然比printf/scanf函数慢得多。我已经几年没有使用C++了... - gawi
显示剩余2条评论

5
除了原始重定向 >/ >><,您还可以重定向 std::cinstd::cout。例如以下方式:
int main()
{
    // Save original std::cin, std::cout
    std::streambuf *coutbuf = std::cout.rdbuf();
    std::streambuf *cinbuf = std::cin.rdbuf(); 

    std::ofstream out("outfile.txt");
    std::ifstream in("infile.txt");

    //Read from infile.txt using std::cin
    std::cin.rdbuf(in.rdbuf());

    //Write to outfile.txt through std::cout 
    std::cout.rdbuf(out.rdbuf());   

    std::string test;
    std::cin >> test;           //from infile.txt
    std::cout << test << "  "; //to outfile.txt

    //Restore back.
    std::cin.rdbuf(cinbuf);   
    std::cout.rdbuf(coutbuf); 

}

0

理解重定向的概念非常重要。重定向将标准输入、标准输出和标准错误输出重新路由。

常见的重定向命令包括:

  • > 重定向命令的标准输出到一个文件,覆盖之前的内容。

    $ command > file

  • >> 重定向命令的标准输出到一个文件,将新的内容追加到旧的内容后面。

    $ command >> file

  • < 重定向命令的标准输入。

    $ command < file

  • | 将一个命令的标准输出重定向到另一个命令。

    $ command | another_command

  • 2> 将错误输出重定向到一个文件。

    $ command 2> file

    $ command > out_file 2> error_file

  • 2>&1 将标准错误输出重定向到与标准输出相同的文件。

    $ command > file 2>&1

您可以组合使用重定向:

# redirect input, output and error redirection
$ command < in_file > out_file  2> error_file
# redirect input and output
$ command < in_file > out_file
# redirect input and error
$ command < in_file 2> error_file
# redirect output and error
$ command > out_file  2> error_file

虽然这不是你的问题的一部分,但是当与重定向命令结合使用时,你也可以使用其他命令:

  • sort:按字母顺序对文本行进行排序。
  • uniq:过滤重复的相邻文本行。
  • grep:搜索文本模式并输出它。
  • sed:搜索文本模式,修改它并输出它。

0

[我只是在解释问题中使用的命令行参数]

您可以将文件名作为命令行输入提供给可执行文件,但然后您需要在代码中打开它们。

例如

您已经提供了两个命令行参数,即inputfile和outputfile

[App.exe inputfile outputfile]

现在在您的代码中

#include<iostream>
#include<fstream>
#include<string>

int main(int argc, char * argv[])
{
   //argv[0] := A.exe
   //argv[1] := inputFile
   //argv[2] := outputFile

   std::ifstream vInFile(argv[1],std::ios::in); 
   // notice I have given first command line argument as file name

   std::ofstream vOutFile(argv[2],std::ios::out | std::ios::app);
   // notice I have given second command line argument as file name

   if (vInFile.is_open())
   {
     std::string line;

     getline (vInFile,line); //Fixing it as per the comment made by MSalters

     while ( vInFile.good() )
     {
         vOutFile << line << std::endl;
         getline (vInFile,line);          
     }
     vInFile.close();
     vOutFile.close();
  }

  else std::cout << "Unable to open file";

  return 0;
}

代码添加了一个虚假的最后一行。当最后一次读取失败时,您首先将“line”写入“vOutFile”,然后才检查“vInFile.good()”。循环中的正确顺序应为:读取行,检查是否读取成功,写入行,跳转到读取。 - MSalters

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