Spec-Zone.ru › C

setvbuf

Определено в заголовке <stdio.h>
int setvbuf( FILE *         stream, char *         buffer, 
             int mode, size_t size );
(до C99)
int setvbuf( FILE *restrict stream, char *restrict buffer, 
             int mode, size_t size );
(с C99)
#define _IOFBF     /*unspecified*/
#define _IOLBF     /*unspecified*/
#define _IONBF     /*unspecified*/

Изменяет режим буферизации указанного потока файла stream в соответствии с аргументом mode. Кроме того,

  • Если buffer является указателем на ноль, изменяет размер внутреннего буфера на size.
  • Если buffer не является указателем на ноль, указывает потоку использовать предоставленный пользователем буфер размером size, начиная с адреса buffer. Поток должен быть закрыт (с помощью fclose) до истечения срока жизни массива, на который указывает buffer. Содержимое массива после успешного вызова setvbuf является неопределенным, и любая попытка его использования ведет к неопределенному поведению.

Параметры

stream - поток файла, для которого необходимо установить буфер
buffer - указатель на буфер для использования потоком или нулевой указатель для изменения только размера и режима
mode - режим буферизации для использования. Может принимать одно из следующих значений:
_IOFBF полная буферизация
_IOLBF строчная буферизация
_IONBF отсутствие буферизации
size - размер буфера

Возвращаемое значение

​0​ при успехе или ненулевое значение при ошибке.

Примечания

Эта функция может быть использована только после того, как stream был связан с открытым файлом, но до выполнения любых других операций (кроме неудачного вызова setbuf/setvbuf).

Не все size байты обязательно будут использоваться для буферизации: фактический размер буфера обычно округляется вниз до кратного 2, кратного размеру страницы и т. д.

Во многих реализациях строчная буферизация доступна только для потоков ввода-вывода с терминалом.

Частая ошибка заключается в установке буфера stdin или stdout в массив, срок жизни которого истекает до завершения программы:

int main(void) {
    char buf[BUFSIZ];
    setbuf(stdin, buf);
} // lifetime of buf ends, undefined behavior

Размер буфера по умолчанию BUFSIZ ожидается как наиболее эффективный размер буфера для ввода-вывода файлов в данной реализации, но POSIX fstat часто предоставляет более точную оценку.

Пример

Один из вариантов использования изменения размера буфера — когда известен более оптимальный размер. (В этом примере используются некоторые функции POSIX, например, fileno. См. также SO: #1 и #2).

// Make some POSIX functions, such as `int fileno(FILE*)`, visible:
#define _POSIX_SOURCE
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
 
int main(void)
{
    FILE* fp = fopen("/tmp/test.txt", "w+");
    if (fp == NULL)
    {
        perror("fopen");
        return EXIT_FAILURE;
    }
 
    struct stat stats;
    if (fstat(fileno(fp), &stats) == -1) // POSIX only
    {
        perror("fstat");
        return EXIT_FAILURE;
    }
 
    printf("BUFSIZ is %d, but optimal block size is %ld\n", BUFSIZ, stats.st_blksize);
    if (setvbuf(fp, NULL, _IOFBF, stats.st_blksize) != 0)
    {
        perror("setvbuf failed"); // POSIX version sets errno
        return EXIT_FAILURE;
    }
 
    int ch;
    while((ch=fgetc(fp)) != EOF); // read entire file: use truss/strace to
                                  // observe the read(2) syscalls used
 
    fclose(fp);
    return EXIT_SUCCESS;
}

Возможный вывод:

BUFSIZ is 8192, but optimal block size is 65536

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.21.5.6 Функция setvbuf (стр. 225)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.21.5.6 Функция setvbuf (стр. 308)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.19.5.6 Функция setvbuf (стр. 273-274)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
    • 4.9.5.6 Функция setvbuf

См. также

setbuf
устанавливает буфер для потока файла
(функция)
Документация C++ для setvbuf

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/io/setvbuf

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API