2016-10-27 2 views
1

У меня есть два действительно больших номера (не более 23 цифр/каждый), и я бы хотел напечатать их в файл так быстро, как это можно сделать. Строки в файле должны выглядеть так:C++ Как написать блок строк в файл?

номер1 [пробел] номер2 [\ n] например. 123456789999999 99999965454644

Мой подход собирает строки в один большой буфер, а когда буфер заполнен, записать его в файл, используя FWRITE().

Самая большая проблема заключается в том, что я не знаю, как создать одну строку из этих двух чисел и сохранить их в один массив string/char. Как я уже упоминал длина строки является переменной величиной, она может быть только 3 символов или даже 50.

const int OUT_BUFFER_SIZE = 65536; 
string out_buffer[OUT_BUFFER_SIZE]; 
int out_size = 0; 
FILE* output_file = fopen("result.out", "w"); 

void print_numbers(FILE* f, long long num1, long long num2) 
{ 
    const int ELEMENT_SIZE = 50; 

    char line[ELEMENT_SIZE]; 
    sprintf(line, "%lld %lld\n", num1, num2); 
    out_buffer[out_size] = line; 
    out_size++; 

    if (out_size == OUT_BUFFER_SIZE) 
    { 
    fwrite(out_buffer, ELEMENT_SIZE, OUT_BUFFER_SIZE, f); 
    } 
} 

fclose(output_file); 

Есть ли другой способ, как решить эту проблему? Благодарю.

edit1: Я попробовал два Addtional подхода:

1) писать числа сразу в файл, используя fprintf(f, "%lld %lld\n", num1, num2);

2) с использованием ofstream точно так же, как упоминалось @somnium.

Я измерил их оба, и удивительно, что 1) подход в 2 раза быстрее, чем второй.

+0

Это не сработает, потому что 'out_buffer' - это массив объектов' std :: string'. Объект 'std :: string' - это не что иное, как указатель на фактическую строку и длину строки. То, что вы будете делать, это писать этот указатель и длину, но не фактическую строку. Вы также можете читать из массива за пределами границ, так как я сомневаюсь, что размер одного объекта 'std :: string' равен целых 50 байт. Если вы хотите быть «быстрым», буфером 'char' и писать это. И вы, вероятно, не хотите использовать C 'FILE *', но прямой (зависящий от системы) небуферизованный ввод-вывод. –

+0

О, и какие другие способы вы пробовали? Вы измерили их, чтобы убедиться, что они не быстрые * достаточно *? Существуют более простые способы записи строк в файл, особенно на C++. Сначала попробуйте это и * measure * it. –

ответ

0

Если вы используете C++, а не обычный C вы можете использовать:

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

void print_numbers(const std::string fname, long long num1, long long num2) 
    ofstream myfile; 
    myfile.open (fname); 
    myfile << num1 << " " << num2 << '\n'; 
    myfile.close(); 
    return 0; 
} 

Это делает необходимую буферизацию, лежащий в основе уже.

+1

Запишите это, чтобы начать все равно (это понятно и легко понять). Если окажется не достаточно быстрым, вы можете его оптимизировать позже. –

+0

заменить '\ n' на std :: endl. Это лучший способ сделать новую строку с помощью iostream. return 0 бесполезен, потому что функция возвращает void. – Stargateur

+1

@ Начальник Я бы не сказал, что это лучше; мы не должны сообщать людям, чтобы потоки потока каждый раз, когда они хотят выпустить новую строку. – TartanLlama

0

Что не так с использованием «fprintf (f,«% lld% lld \ n », num1, num2);»? fprintf использует буферизованный IO, поэтому нет смысла добавлять еще один уровень буферизации. Если вы хотите увеличить размер буфера, вы можете использовать setvbuf() для этого.

Однако самый быстрый способ, вероятно, состоял бы в том, чтобы избежать какой-либо буферизации и передать все данные, которые должны быть записаны в writev(), который берет набор буферов для записи одним системным вызовом. Тем не менее, рассмотрение частичной записи (которую можно разрешить writev) не является тривиальным.

+0

Я не знал, что fprintf использует буферизованный IO. Благодарю. – Alex