2011-01-20 3 views
0

Я пытался вызвать другую программу из C++ и сохранить ее в текстовом файле. popen() кажется подходящей функцией, но сохранение его в текстовый файл не работает.Запись файла popen() в файл

 ofstream delaunayfile; 
    delaunayfile.open ("triangulation/delaunayedpoints.txt"); 
     FILE *fp; 
     fp = popen("qdelaunay < triangulation/rawpoints.txt", "r"); 
    delaunayfile << fp; 
    delaunayfile.close(); 

Любая помощь? Заранее спасибо!

ответ

0

Есть два способа сделать это: Простой способ

int rc = system("qdelaunay <triangulation/rawpoints.txt>triangulation/delaunayedpoints.txt"); 

и чуть более сложный способ, с помощью вилки(), dup2() и execve(), последний работает без переводчика оболочки установлен в системе. Учитывая, что это выглядит так, как будто вы выполняете вычислительную работу, я подозреваю, что это не встроенная система, поэтому вы можете принять рабочую оболочку.

0

popen открывает трубку, но я не знаю, что вы можете просто передать ее в delaunayfile таким образом.

Конечно, было бы очень приятно, если бы вы могли просто сделать это, и он будет читать из трубы до тех пор, пока он не будет завершен.

Обычный способ проверки данных на трубе - использовать select(). Я нашел полезную ссылку http://codenewbie.com/forums/threads/2908-Using-std-fstream-in-a-pipe, которая объединяет трубы с fstream, хотя это может помочь вам добиться того, чего вы хотите.

В этом случае, хотя все, что вы хотите сделать, это записать вывод в файл, почему бы не перенаправить вывод процесса на него, а не в трубу? Целью канала является межпроцессное взаимодействие, но ваш процесс, похоже, не использует данные, полученные им от другого процесса, для каких-либо практических целей.

2

Вы не можете написать FILE* прямо в поток. Он будет записывать адрес памяти вместо фактического содержимого файла, поэтому он не даст желаемого результата.

Идеальным решением было бы читать из ifstream и записать на свой ofstream, но нет никакого способа, чтобы построить ifstream из FILE*.

Однако мы можем расширить класс streambuf, чтобы он работал над FILE*, а затем передал его istream. Быстрый поиск показал, что кто-то уже реализовал это и правильно назвал popen_streambuf. См. this specific answer.

Ваш код тогда будет выглядеть следующим образом:

std::ofstream output("triangulation/delaunayedpoints.txt"); 
popen_streambuf popen_buf; 
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) { 
    std::cerr << "Failed to popen." << std::endl; 
    return; 
} 
char buffer[256]; 
std::istream input(&popen_buf); 
while (input.read(buffer, 256)) { 
    output << buffer; 
} 
output.close(); 

Как указано на Simon Richter в комментариях, есть operator<<, который принимает streambuf и записывает данные в ostream до EOF не будет достигнута. Таким образом, код будет упрощено до:

std::ofstream output("triangulation/delaunayedpoints.txt"); 
popen_streambuf popen_buf; 
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) { 
    std::cerr << "Failed to popen." << std::endl; 
    return; 
} 
output << &popen_buf; 
output.close(); 
+1

отметить, что в вашем примере, вы также можете использовать 'вывода << и popen_buf,' чтобы скопировать данные, так как есть 'оператор << (станд :: ostream &, std :: streambuf *); '. –

+0

@ Симон Рихтер: О, я полностью пропустил это! Обновлено, чтобы упомянуть ваше предложение. Спасибо! – jweyrich

Смежные вопросы