2015-09-22 1 views
0

Программа 1:Setbuf функция в C

#include<stdio.h> 
    void main() 
    { 
     printf("Hello\n"); 
    } 

Выход:

$strace ./a.out 
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 
    fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 
    . 
    . 
    . 
    . 
    write(1, "Hello\n", 6Hello 
    )     = 6 
    exit_group(6)       = ? 
    $ 

Программа 2:

#include<stdio.h> 
    void main() 
    { 
     char buf[2]; 
     setbuf(stdout,buf); 
     printf("Hello\n"); 
    } 

Выход:

$ strace ./a.out 
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 
    fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 
    . 
    . 
    . 
    . 
    write(1, "Hello\n", 6Hello 
    )     = 6 
    exit_group(6)       = ? 
    $ 

Мое требование - найти функцию setbuf. Итак, я экспериментировал две программы, которые показаны выше. В программе 1, я не установить буфер в стандартный вывод. Таким образом, он использует встроенный буфер. Размер встроенного буфера составляет 4096 (приблизительно). Для этого Hello достаточно для записи . Таким образом, системный вызов write будет вызываться только один раз.

Но в программе 2 я явно задал буфер размером 2 символа. Таким образом, printf использует этот буфер. Итак, мой ожидаемый результат равен , что систему записи следует вызывать в 3-4 раза. Но выход strace для обеих программ остается таким же.

Так что в программе 2 функция printf использует буфер (buf). Если он используется buf, то системный вызов будет вызываться 4 раза. Итак, как я могу проверить, сколько раз моя функция записи вызова функции «a.out».

+2

Опять же, ** void main() {} ** должен быть ** int main (void) {} ​​** – Michi

ответ

5

Проблема заключается в том, что setbuf() не определяет размер буфера, то предполагается BUFSIZ, не 2, потому что функция никогда не будет видеть, что 2.

И так как, скорее всего, BUFSIZ greated, чем 2 у вас есть переполнение буфера!

Это довольно неудобно, и именно поэтому есть новый setvbuf():

int setvbuf(FILE *stream, char *buf, int mode, size_t size); 

Это будет использоваться, например, как:

setvbuf(stdout, buf, _IOFBF, sizeof(buf)); 

PS: Вы не должны писать void main(), использовать int main() вместо этого.

+0

Если я изменил значение макроса BUFSIZ на 2. Затем? – mrg

+0

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

+0

@mohan: No !, 'BUFSIZ' - это предопределенный макрос, который сообщает вам, какой размер буфера ожидает стандартная библиотека. Изменение макроса не изменит библиотеку (если вы не перекомпилируете 'libc', и вы этого не хотите). – rodrigo