П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 4019 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 6656 раз(а).

Учебник HTML.
Просмотров 3646 раз(а).

Руководство по PHP5.
Просмотров 5924 раз(а).

Хостинг через призму DNS.
Просмотров 4707 раз(а).

Подборка текстов стандартных документов.
Просмотров 56174 раз(а).

Учебник PHP - Самоучитель
Просмотров 3603 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 8049 раз(а).

Внешние атаки...
Просмотров 4431 раз(а).

Учебник PHP.
Просмотров 3119 раз(а).

SSI в примерах.
Просмотров 137 раз(а).






 
 
| Добавить в избранное | Сделать стартовой Project.Net.Ru | Помощь





Время поиграть

Мы начинаем изучение использования и поведения данного формата при помощи маленьких программ. Первая, printf1, демонстрирует очень простое использование:

/* printf1.c */
1: #include <stdio.h>
2:
3: main() {
4:   char *buf = "0123456789";
5:   int n;
6:
7:   printf("%s%n\n", buf, &n);
8:   printf("n = %d\n", n);
9: }

Первый вызов printf() выводит строку "0123456789", которая содержит 10 символов. Следующий формат %n записывает данное значение в переменную n:

>>gcc printf1.c -o printf1
>>./printf1
0123456789
n = 10
Давайте немного изменим нашу программу заменяя инструкцию printf() строки 7 на:
7:   printf("buf=%s%n\n", buf, &n);

Запуск новой программы подтверждает нашу идею: переменная n сейчас равна 14 (10 символов из строковой переменной buf добавляются к 4 символам строки-константы "buf=", содержащейся в самой строке форматирования).

Итак, мы знаем, что формат %n подсчитывает каждый символ, который появляется в строке форматирования. Более того, как мы продемонстрируем программой printf2, он подсчитывает еще кое-что:

/* printf2.c */

#include <stdio.h>

main() {
  char buf[10];
  int n, x = 0;

  snprintf(buf, sizeof buf, "%.100d%n", x, &n);
  printf("l = %d\n", strlen(buf));
  printf("n = %d\n", n);
}
Мы используем здесь функцию snprintf(), чтобы не допустить переполнение буфера. Переменная n должна быть равна 10:
>>gcc printf2.c -o printf2
>>./printf2
l = 9
n = 100
Странно? Фактически, формат %n учитывает количество символов, которые должны быть выведены. Этот пример показывает, что обрезание из-за указания размера буфера игнорируется.

Что происходит на самом деле? Строка форматирования полностью расширяется перед тем, как она урезается и затем копируется в буфер назначения:

/* printf3.c */

#include <stdio.h>

main() {
  char buf[5];
  int n, x = 1234;

  snprintf(buf, sizeof buf, "%.5d%n", x, &n);
  printf("l = %d\n", strlen(buf));
  printf("n = %d\n", n);
  printf("buf = [%s] (%d)\n", buf, sizeof buf);
}
printf3 немного отличается от printf2:
  • размер буфера уменьшен до 5 байт;
  • точность в строке форматирования теперь установлена в 5;
  • в конце выводится содержимое буфера.
Мы получаем следующее:
>>gcc printf3.c -o printf3
>>./printf3
l = 4
n = 5
buf = [0123] (5)
В первых двух строках нет ничего удивительного. Последняя показывает нам поведение функции printf():
  1. Строка форматирования расширяется, согласно командам1 в ней содержащихся, из-за чего получаем строку "00000\0";
  2. Переменные записываются куда и как надо, что показано копированием x в нашем примере. Строка теперь выглядит "01234\0";
  3. последнее, sizeof buf - 1 байт2 из этой строки копируется в строку назначения buf, что дает нам "0123\0"
Это все происходит не точно так как описано, однако описание отражает основные процессы. Для подробностей читатель должен обратиться к исходникам GlibC, конкретно к vfprintf() в директории ${GLIBC_HOME}/stdio-common.

Перед тем как закончить эту часть, добавим, что возможно получить тот же результат записывая строку форматирования немного в другой форме. Мы использовали формат, называемый точность (точка '.'). Другая комбинация инструкций форматирования приводит к тому же результату: 0n, где n - обозначает ширину, а 0 обозначает, что лишние позиции будут заполнены 0, если вся ширина не будет заполнена.

Теперь, когда вы знаете почти все о строках форматирования, а более конкретно о формате %n, мы изучим их поведение.

Назад | Содержание | Вперед



Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru