Làm thế nào để chuyển hướng cin và cout vào tập tin?


Câu trả lời:


219

Dưới đây là một ví dụ làm việc về những gì bạn muốn làm. Đọc các bình luận để biết mỗi dòng trong mã làm gì. Tôi đã thử nghiệm nó trên máy tính của mình với gcc 4.6.1; nó hoạt động tốt.

#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
}

Bạn có thể lưuchuyển hướng chỉ trong một dòng như:

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

Ở đây std::cin.rdbuf(in.rdbuf())thiết lập bộ std::cin'sđệm in.rdbuf()và sau đó trả về bộ đệm cũ được liên kết với std::cin. Điều tương tự có thể được thực hiện với std::cout- hoặc bất kỳ luồng nào cho vấn đề đó.

Mong rằng sẽ giúp.


4
Tôi có cần phải đóng các tệp trước khi đặt lại cin và cout thành IO chuẩn không?
updogliu

3
@updogliu: Không. Nếu bạn muốn, bạn có thể sử dụng inoutđọc từ và viết thư, in.txtout.txttương ứng. Ngoài ra, các tệp sẽ được đóng tự động khi inoutđi ra khỏi phạm vi.
Nawaz

Tôi thích giải pháp này hơn freopenmột vì tôi không còn có thể lấy stdoutlại nếu tôi sử dụng freopen. stackoverflow.com/questions/26699524/
xxks-kkk

88

Chỉ viết

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

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

14
Đó là chuyển hướng stdout, không phải cout.
updogliu

5
Điều này cũng sẽ chuyển hướng printf, trong một số trường hợp có thể là một điều tốt.
JDiMatteo

5
@AkshayLAradhya Không phải khi bạn đặt std::sync_with_studio(false);, mặc dù theo mặc định, nó được đặt thành true.
vsoftco

2
@ PřemyslŠťastný tại sao?
reggaeg Ức

4
Nếu các câu trả lời có chức năng như nhau, thì C ++ tương đương với điều này sẽ là ofstream out("out.txt"); cout.rdbuf(out.rdbuf());- chỉ có một dòng bổ sung và nó có thể mang theo được. Không đơn giản hơn nhiều :)
nevelis

19

Dưới đây là đoạn mã ngắn để tạo bóng cin / cout hữu ích cho các cuộc thi lập trình:

#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;
}

Điều này mang lại lợi ích bổ sung rằng các luồng đơn giản nhanh hơn các luồng stdio được đồng bộ hóa. Nhưng điều này chỉ hoạt động cho phạm vi của chức năng duy nhất.

Chuyển hướng cin / cout toàn cầu có thể được viết là:

#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();
}

Lưu ý rằng ios_base::sync_with_stdiocũng đặt lại std::cin.rdbuf. Vì vậy, thứ tự quan trọng.

Xem thêm Ý nghĩa của ios_base :: sync_with_stdio (false); cin.tie (NULL);

Các luồng Std io cũng có thể dễ dàng bị che khuất cho phạm vi của một tệp duy nhất, rất hữu ích cho lập trình cạnh tranh:

#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();
}

Nhưng trong trường hợp này, chúng ta phải chọn từng stdkhai báo và tránh using namespace std;vì nó sẽ gây ra lỗi mơ hồ:

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
                   ^

Xem thêm Làm thế nào để bạn sử dụng đúng không gian tên trong C ++? , Tại sao "sử dụng không gian tên std" được coi là thực tiễn xấu? Làm thế nào để giải quyết xung đột tên giữa không gian tên C ++ và hàm toàn cục?


15

giả sử tên prog biên dịch của bạn là x.exe và $ là hệ thống hoặc dấu nhắc hệ thống

$ x <infile >outfile 

sẽ lấy đầu vào từ infile và sẽ xuất ra outfile.


Điều đó không liên quan đến C ++ và thất bại trong bất kỳ ví dụ không tầm thường nào, ví dụ như khi chương trình của bạn sinh ra các tiến trình con ghi vào bàn điều khiển. Ít nhất đó là vấn đề tôi gặp phải khi tôi thử chuyển hướng như vậy, tại sao tôi lại ở đây.
ashrasmun

5

Hãy thử điều này để chuyển hướng cout đến tập tin.

#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;
}

Đọc toàn bộ bài viết Sử dụng std :: rdbuf để Chuyển hướng cin và cout


1
Câu hỏi đã được trả lời gần 6 năm trước (năm 2012), nhưng bạn đã thêm câu trả lời ngay bây giờ vào năm 2018. Câu trả lời của bạn giống như câu trả lời được chấp nhận. Vì vậy, tôi tự hỏi tại sao bạn đăng bài này khi bạn không có mới để thêm?
Nawaz

Câu trả lời của tôi chỉ nêu bật phiên bản cout đặc biệt và câu trả lời chi tiết được cung cấp trong liên kết bên dưới.
HaseeB Mir

Có gì mới trong câu trả lời của bạn không có trong câu trả lời được chấp nhận ?
Nawaz

2
Câu trả lời của tôi không kết hợp chuyển hướng của cả cout và cin, phiên bản của tôi tách ra để dễ đọc hơn
HaseeB Mir
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.