จะเปลี่ยนเส้นทาง cin และ cout ไปยังไฟล์ได้อย่างไร


133

ฉันcinจะเปลี่ยนเส้นทางไปin.txtและcoutกลับได้out.txtอย่างไร


8
เปลี่ยนเส้นทาง cin ไปยังสตริง: stackoverflow.com/questions/4925150/redirect-cin-to-a-string - เปลี่ยนเส้นทางไปยังสตริง: stackoverflow.com/questions/1162068/…
Dr.Kameleon

คำตอบ:


219

นี่คือตัวอย่างการทำงานของสิ่งที่คุณต้องการทำ อ่านความคิดเห็นเพื่อทราบว่าแต่ละบรรทัดในโค้ดทำหน้าที่อะไร ฉันได้ทดสอบบนพีซีของฉันด้วย gcc 4.6.1; มันใช้งานได้ดี

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

void f()
{
    std::string line;
    while(std::getline(std::cin, line))  //input from the file in.txt
    {
        std::cout << line << "\n";   //output to the file out.txt
    }
}
int main()
{
    std::ifstream in("in.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf
    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!

    std::ofstream out("out.txt");
    std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!

    std::string word;
    std::cin >> word;           //input from the file in.txt
    std::cout << word << "  ";  //output to the file out.txt

    f(); //call function


    std::cin.rdbuf(cinbuf);   //reset to standard input again
    std::cout.rdbuf(coutbuf); //reset to standard output again

    std::cin >> word;   //input from the standard input
    std::cout << word;  //output to the standard input
}

คุณสามารถบันทึกและเปลี่ยนเส้นทางในบรรทัดเดียวเป็น:

auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect

นี่std::cin.rdbuf(in.rdbuf())ชุดstd::cin'sbuffer ไปแล้วกลับบัฟเฟอร์เก่าที่เกี่ยวข้องกับin.rdbuf() std::cinเช่นเดียวกันสามารถทำได้ด้วยstd::cout- หรือสตรีมใด ๆสำหรับเรื่องนั้น

หวังว่าจะช่วยได้


4
ฉันต้องปิดไฟล์ก่อนที่จะรีเซ็ต cin และ cout เป็น IO มาตรฐานหรือไม่
updogliu

3
@updogliu: ไม่ถ้าคุณต้องการคุณสามารถใช้inและoutเพื่ออ่านและเขียนถึงin.txtและout.txtตามลำดับ นอกจากนี้ไฟล์จะถูกปิดโดยอัตโนมัติเมื่อinและoutออกนอกขอบเขต
Nawaz

ผมชอบวิธีนี้มากกว่าfreopenหนึ่งเพราะผมไม่สามารถรับฉันกลับถ้าผมใช้stdout stackoverflow.com/questions/26699524/…freopen
xxks-kkk

88

แค่เขียน

#include <cstdio>
#include <iostream>
using namespace std;

int main()
{
    freopen("output.txt","w",stdout);
    cout<<"write in file";
    return 0;
}

14
นั่นคือการเปลี่ยนเส้นทางไม่stdout cout
updogliu

5
ซึ่งจะเปลี่ยนเส้นทาง printf ไปด้วยซึ่งในบางกรณีอาจเป็นเรื่องดี
JDiMatteo

5
@AkshayLAradhya ไม่ใช่เมื่อคุณตั้งค่าstd::sync_with_studio(false);แม้ว่าโดยค่าเริ่มต้นจะตั้งเป็นtrue.
vsoftco

2
@ PřemyslŠťastnýทำไม?
reggaeguitar

4
หากคำตอบเท่ากันในฟังก์ชันการทำงานที่เทียบเท่า C ++ จะเป็นofstream out("out.txt"); cout.rdbuf(out.rdbuf());เพียงบรรทัดเดียวพิเศษและเป็นแบบพกพา ไม่ง่ายกว่านี้มาก :)
nevelis

19

นี่คือตัวอย่างโค้ดสั้น ๆ สำหรับการทำเงา cin / cout ที่มีประโยชน์สำหรับการแข่งขันการเขียนโปรแกรม:

#include <bits/stdc++.h>

using namespace std;

int main() {
    ifstream cin("input.txt");
    ofstream cout("output.txt");

    int a, b;   
    cin >> a >> b;
    cout << a + b << endl;
}

สิ่งนี้ให้ประโยชน์เพิ่มเติมที่ fstreams ธรรมดาเร็วกว่าสตรีม stdio ที่ซิงค์ แต่จะใช้ได้เฉพาะกับขอบเขตของฟังก์ชันเดียวเท่านั้น

การเปลี่ยนเส้นทาง cin / cout ส่วนกลางสามารถเขียนเป็น:

#include <bits/stdc++.h>

using namespace std;

void func() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << endl;
}

int main() {
    ifstream cin("input.txt");
    ofstream cout("output.txt");

    // optional performance optimizations    
    ios_base::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin.rdbuf(cin.rdbuf());
    std::cout.rdbuf(cout.rdbuf());

    func();
}

ทราบว่ายังมีการตั้งค่าใหม่ios_base::sync_with_stdio std::cin.rdbufดังนั้นการสั่งซื้อจึงมีความสำคัญ

ดูความสำคัญของ ios_base :: sync_with_stdio (false); cin.tie (NULL);

สตรีม Std io สามารถกำหนดขอบเขตของไฟล์เดียวได้อย่างง่ายดายซึ่งมีประโยชน์สำหรับการเขียนโปรแกรมเชิงแข่งขัน:

#include <bits/stdc++.h>

using std::endl;

std::ifstream cin("input.txt");
std::ofstream cout("output.txt");

int a, b;

void read() {
    cin >> a >> b;
}

void write() {
    cout << a + b << endl;
}

int main() {
    read();
    write();
}

แต่ในกรณีนี้เราต้องเลือกstdการประกาศทีละรายการและหลีกเลี่ยงusing namespace std;เนื่องจากจะทำให้เกิดข้อผิดพลาดที่ไม่ชัดเจน:

error: reference to 'cin' is ambiguous
     cin >> a >> b;
     ^
note: candidates are: 
std::ifstream cin
    ifstream cin("input.txt");
             ^
    In file test.cpp
std::istream std::cin
    extern istream cin;  /// Linked to standard input
                   ^

ดูเพิ่มเติมคุณใช้เนมสเปซใน C ++ อย่างไร? , เหตุใด "การใช้เนมสเปซ std" จึงถือว่าเป็นการปฏิบัติที่ไม่ดี และจะแก้ไขการชนกันของชื่อระหว่างเนมสเปซ C ++ และฟังก์ชันส่วนกลางได้อย่างไร


15

สมมติว่าชื่อ prog คอมไพล์ของคุณคือ x.exe และ $ คือเชลล์ของระบบหรือพร้อมต์

$ x <infile >outfile 

จะรับอินพุตจาก infile และจะส่งออกไปยัง outfile


ไม่เกี่ยวข้องกับ C ++ และล้มเหลวในตัวอย่างที่ไม่สำคัญเช่นเมื่อโปรแกรมของคุณสร้างกระบวนการย่อยที่เขียนลงในคอนโซล อย่างน้อยนั่นก็เป็นปัญหาที่ฉันพบเมื่อฉันลองเปลี่ยนเส้นทางดังนั้นฉันจึงมาที่นี่
ashrasmun

5

ลองใช้วิธีนี้ในการเปลี่ยนเส้นทางศาลไปยังแฟ้ม

#include <iostream>
#include <fstream>

int main()
{
    /** backup cout buffer and redirect to out.txt **/
    std::ofstream out("out.txt");

    auto *coutbuf = std::cout.rdbuf();
    std::cout.rdbuf(out.rdbuf());

    std::cout << "This will be redirected to file out.txt" << std::endl;

    /** reset cout buffer **/
    std::cout.rdbuf(coutbuf);

    std::cout << "This will be printed on console" << std::endl;

    return 0;
}

อ่านบทความเต็มใช้ std :: rdbuf เพื่อเปลี่ยนเส้นทาง cin และ cout


1
คำถามนี้ได้รับคำตอบเมื่อเกือบ 6 ปีก่อน (ในปี 2012) แต่คุณได้เพิ่มคำตอบแล้วในปี 2018 คำตอบของคุณเหมือนกับคำตอบที่ยอมรับ ฉันสงสัยว่าทำไมคุณถึงโพสต์สิ่งนี้ในเมื่อคุณไม่มีอะไร ใหม่ให้เพิ่ม?
Nawaz

คำตอบของฉันเน้นเฉพาะรุ่น cout เป็นพิเศษและคำตอบโดยละเอียดอยู่ในลิงค์ด้านล่าง
HaseeB Mir

มีอะไรใหม่ในคำตอบของคุณซึ่งไม่มีอยู่ในคำตอบที่ยอมรับ
Nawaz

2
คำตอบของฉันไม่ได้ผสมการเปลี่ยนเส้นทางของทั้ง cout และ cin เวอร์ชันของฉันแยกออกจากกันเพื่อให้อ่านง่ายขึ้น
HaseeB Mir
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.