2010-09-08 8 views
1
#include <iostream> 
#include <fstream> 
using namespace std; 

void foo(){ 
    streambuf *psbuf; 
    ofstream filestr; 
    filestr.open ("test.txt"); 
    psbuf = filestr.rdbuf(); 
    cout.rdbuf(psbuf);  
} 

int main() { 
    foo(); 
    cout << "This is written to the file"; 
    return 0; 
} 

Выполняет ли cout запись в данный файл?Перенаправление в C++

Если нет, есть ли способ сделать это без отправки переменных в foo, например new?


обновление:

Я не могу использовать решение, которое использует класс или использует глобальные так плз могут некоторые дать мне решение, использовать новый. Также прохождение от главного к foo

streambuf *psbuf; 
ofstream filestr; 

должно работать правильно?

Я пытаюсь сделать это, но не работает? Я передаю поток в foo, так что он существует в главном, так что он не закончится, когда закончится foo.

void foo(streambuf *psbuf){ 

    ofstream filestr; 
    filestr.open ("test.txt"); 
    psbuf = filestr.rdbuf(); 
    cout.rdbuf(psbuf);  
} 

int main() { 
streambuf *psbuf 
    foo(psbuf); 
    cout << "This is written to the file"; 
    return 0; 
} 

ответ

1

Мне кажется, что ваш код должен работать, но ... Почему бы вам не попробовать себя? Вы увидите, все ли написано в test.txt или нет.

+0

Мне кажется, что это не так, но ваш вопрос остается в силе :-) – Johnsyweb

+1

@johnsyweb Oh правой filestr разрушается. Я не читал внимательно ... – log0

4

Я подозреваю, что к настоящему времени скомпилирован и запущен ваш код и обнаружено, что вы получаете ошибку сегментации.

Вы получаете это, потому что вы создаете и открываете объект ofstream в пределах foo(), который затем уничтожается (и закрывается) в конце foo. При попытке записи в поток в main() вы пытаетесь получить доступ к буферу, который больше не существует.

Один обходной путь к этому должен сделать ваш filestr объект глобальный. Есть много лучших!

Edit: Вот лучшее решение, как было предложено @MSalters:

#include <iostream> 
#include <fstream> 

class scoped_cout_redirector 
{ 
public: 
    scoped_cout_redirector(const std::string& filename) 
     :backup_(std::cout.rdbuf()) 
     ,filestr_(filename.c_str()) 
     ,sbuf_(filestr_.rdbuf()) 
    { 
     std::cout.rdbuf(sbuf_); 
    } 

    ~scoped_cout_redirector() 
    { 
     std::cout.rdbuf(backup_); 
    } 

private: 
    scoped_cout_redirector(); 
    scoped_cout_redirector(const scoped_cout_redirector& copy); 
    scoped_cout_redirector& operator =(const scoped_cout_redirector& assign); 

    std::streambuf* backup_; 
    std::ofstream filestr_; 
    std::streambuf* sbuf_; 
}; 


int main() 
{ 
    { 
     scoped_cout_redirector file1("file1.txt"); 
     std::cout << "This is written to the first file." << std::endl; 
    } 


    std::cout << "This is written to stdout." << std::endl; 

    { 
     scoped_cout_redirector file2("file2.txt"); 
     std::cout << "This is written to the second file." << std::endl; 
    } 

    return 0; 
} 
+1

«Есть лучшие». В самом деле, но было бы трудно найти их без указателя. Вот один: читать RAII. Большая часть кода из функции 'foo' должна действительно быть перемещена в конструктор, и соответствующий деструктор должен выполнить очистку (например, восстановление cout до своего старого состояния). – MSalters

+0

Действительно. Кажется, что @mati сознательно пропустил восстановление 'cout' до своего прежнего состояния при снятии кода из http://www.cplusplus.com/reference/iostream/ios/rdbuf/ в' foo() '. RAII казался слишком далеко от сферы вопроса. – Johnsyweb