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

О проекте

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

MySQL

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

Хостинг

Другое








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

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

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

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

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

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

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

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

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

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

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

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






 
 
| Добавить в избранное | Сделать стартовой 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