2009-06-21 2 views
1

Я пишу программу для разделения файлов, чтобы помочь с использованием больших файлов с нотами iPod. Я хочу использовать tmpfile() в cstdio, но он возвращает файл *, а не объект fstream. Я знаю, что это невозможно в стандартном C++, но кто-нибудь знает какие-либо библиотеки, которые хорошо работают со стандартом, способным преобразовывать FILE * в объект std :: fstream? Или, если нет функции tmpfile(), доступной в стандарте или другой библиотеке?Смешивание операций с файлами C и C++

Спасибо!

Моя ОС - Windows XP, и я использую Dev-C++ 4.9.9.2 или MS Visual Studio 2008 в качестве моего компилятора.

+1

Точный дубликат: http://stackoverflow.com/questions/109449/getting-a-file-from-a-stdfstream/109522 –

ответ

2

Если все, что вы хотите, это временный файл, используйте tmpnam() вместо этого. Это возвращает имя char *, которое может использоваться для временного файла, поэтому просто откройте объект Fstream с этим именем.

Что-то вроде:

#include <cstdio> 
#include <fstream> 

... 
char name[L_tmpnam]; 
tmpnam(name); 

//also could be: 
//char *name; 
//name = tmpnam(NULL); 

std::fstream file(name); 

Вы должны удалить файл самостоятельно, хотя, используя remove() или какой-либо другой метод.

+1

** Из справочной системы: ** Функция 'tmpnam()' возвращает указатель на строку, которая является допустимым именем файла, и поэтому файл с таким именем не существовал в какой-то момент времени, так что наивные программисты могут считайте это подходящим именем для временного файла. ** Ошибки: никогда не используйте эту функцию ** Вместо этого используйте 'mkstemp (3)' или 'tmpfile (3)'. – Sameer

0

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

char *name; 
ifstream stream; 

name = mktmp("filename"); 
stream.open(name); 
//do stuff with stream here. 

remove(name);//delete file. 
+1

Это не считается безопасной практикой, поскольку кто-то теоретически может вводить файл с выбранное имя в каталог temp, прежде чем вы сможете его открыть. На странице man для tmpnam (3) указано: «Никогда не используйте эту функцию. Вместо этого используйте mkstemp (3) или tmpfile (3)». –

+0

@Tyler McHenry Спасибо, редактирование. – Tom

+1

mktemp так же плохо, как tmpnam - как говорит @Tyler, вам нужен mkstemp или tmpfile. Не существует безопасного способа получить «временное имя» для «временного файла, который не является временным (не исчезает при закрытии)». –

0

Даже если вам удастся преобразовать FILE * в std :: fstream, это не будет работать так, как было объявлено. Объект FILE, возвращаемый tmpfile(), имеет специальное свойство, которое, когда close() 'd (или когда программа завершается), файл автоматически удаляется из файловой системы. Я не знаю, как копировать одно и то же поведение с помощью std :: fstream.

0

Вместо использования std :: fstream вы можете написать простой класс оболочки вокруг FILE *, который закрывает его при уничтожении. Должно быть довольно легко. Определите операторы, такие как < < при необходимости. Обязательно запретите копирование, чтобы избежать множественных вызовов close().

2

Вы можете использовать преимущество C++ потоков путем закачки данных с помощью синтаксиса < < в станд :: stringstream , а затем записать его в .str(). C_str() вы получите от него через С- API для FILE *.

 
#include <sstream> 
#include <cstdio> 
#include <string> 

using namespace std; 

int main() 
{ 
    stringstream ss; 
    ss << "log start" << endl; 

    // ... more logging 

    FILE* f_log = fopen("bar.log", "w"); 
    string logStr = ss.str(); 
    fwrite(logStr.c_str(), sizeof(char), logStr.size(), f_log); 
    fclose(f_log); 

    return 0; 
} 
+0

Вы можете использовать 'FILE * f_log = tmpfile();', чтобы гарантировать, что вы получите уникальный временный файл в двоичном режиме r/w. Это автоматически удаляется после завершения программы. – Sameer

0

g ++ имеет __gnu_cxx::stdio_filebuf и __gnu_cxx::stdio_sync_filebuf, в ext/stdio_filebuf.h и ext/stdio_sync_filebuf.h. Это должно быть прямолинейно, чтобы извлечь их из libstdC++, если ваш компилятор не является g ++.

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