YAML за 5 минут: синтаксис и основные возможности
Однострочные последовательности выглядят лаконичнее, но хуже читаются.
Форматированный ввод и вывод
Теги: Форматированный ввод, форматированный вывод, printf, scanf, fgets, getch, строка формата, спецификатор формата, флаги, управляющие символы.
Форматированный вывод
Сегодня мы рассмотрим две важные функции форматированного ввода и вывода. Устройство и работу этих функций полностью можно понять только после изучения работы с указателями и функций с переменным числом параметров. Но пользоваться этими функциями необходимо уже сейчас, так что некоторые моменты придётся пропустить.
Функция форматированного вывода printf получает в качестве аргументов строку формат и аргументы, которые необходимо вывести в соответствии с форматом, и возвращает число выведенных символов. В случае ошибки возвращает отрицательное значение и устанавливает значение ferror. Если произошло несколько ошибок, errno равно EILSEQ.
int printf (const char * format, . );
#include #include void main() < //функция не получает никаких аргументов, кроме строки printf("Hello world"); getch(); >
Функция проходит по строке и заменяет первое вхождение % на первый аргумент, второе вхождение % на второй аргумент и т.д. Далее мы будем просто рассматривать список флагов и примеры использования.
Общий синтаксис спецификатора формата
%[флаги][ширина][.точность][длина]спецификатор
Спецификатор – это самый важный компонент. Он определяет тип переменной и способ её вывода.
| Спецификатор | Что хотим вывести | Пример |
|---|---|---|
| d или i | Целое со знаком в в десятичном виде | 392 |
| u | Целое без знака в десятичном виде | 7235 |
| o | Беззнаковое в восьмеричном виде | 657 |
| x | Беззнаковое целое в шестнадцатеричном виде | 7fa |
| X | Беззнаковое целое в шестнадцатеричном виде, верхний регистр | 7FA |
| f или F | Число с плавающей точкой | 3.4563745 |
| e | Экспоненциальная форма для числа с плавающей точкой | 3.1234e+3 |
| E | Экспоненциальная форма для числа с плавающей точкой, верхний регистр | 3.1234E+3 |
| g | Кратчайшее из представлений форматов f и e | 3.12 |
| G | Кратчайшее из представлений форматов F и E | 3.12 |
| a | Шестнадцатеричное представление числа с плавающей точкой | -0xc.90fep-2 |
| A | Шестнадцатеричное представление числа с плавающей точкой, верхний регистр | -0xc.90FEP-2 |
| c | Буква | a |
| s | Строка (нуль-терминированный массив букв) | Hello World |
| p | Адрес указателя | b8000000 |
| n | Ничего не печатает. Аргументом должен быть указатель на signed int. По этому адресу будет сохранено количество букв, которое было выведено до встречи %n | |
| % | Два идущих друг за другом процента выводят знак процента | % |
#include #include void main()
Строка формата также может включать в себя следующие необязательные суб-спецификаторы: флаг, ширина, .точность и модификатор (именно в таком порядке).
| Флаг | Описание |
|---|---|
| – | Выключка влево на заданное шириной значение |
| + | Явно указывать знак у числа, даже для положительных чисел |
| (пробел) | Если знак не будет выведен, то вставляет пробел перед выводимым числом |
| # | Когда используется вместе с o, x или X, вставляет перед числом 0, 0x или 0X Когда используется со спецификаторами a, A, e, E, f, F, g или G, вставляет десятичную точку, даже если после неё нет десятичных знаков. |
| 0 | Вставляет нули, когда объявлен спецификатор ширины |
| Ширина | Описание |
|---|---|
| (число) | Минимальное количество знаков, которое необходимо вывести. Если в числе меньше знаков, то вставляет пробелы (или нули) |
| * | Ширина не указана в строке формата, она передаётся отдельно в виде аргумента, который должен предшествовать выводимому числу |
| .Точность | Описание |
|---|---|
| .число | Для спецификаторов целых (d, i, o, u, x, X) точность определяет минимальное количество знаков, которое необходимо вывести. Если значение короче, то выводятся нули перед числом. Значение не обрезается, даже если оно длиннее. Точночть 0 означает, что для значения 0 ничего не выводится. Для спецификаторов чисел с плавающей точкой (a, A, e, E, f, F) это число знаков, которые необходимо вывести после десятичной точки (по умолчанию 6). Для g и G – это число значащих разрядов, которые необходимо вывести. Для s – выводится указанное число символов. По умолчанию выводятся все символы до первого нулевого. Если число не стоит, то по умолчанию точность равна 0 |
| .* | Точность не указана в строке формата, она передаётся отдельно в виде аргумента, который должен предшествовать выводимому числу |
#include #include void main()
Суб-спецификатор длины изменяет длину типа. В случае, если длина не совпадает с типом, по возможности происходит преобразование до нужного типа.
| спецификаторы | |||||||
|---|---|---|---|---|---|---|---|
| Длина | d, i | u o x X | f F e E g G a A | c | s | p | n |
| (none) | int | unsigned int | double | int | char* | void* | int* |
| hh | signed char | unsigned char | signed char* | ||||
| h | short int | unsigned short int | short int* | ||||
| l | long int | unsigned long int | wint_t | wchar_t* | long int* | ||
| ll | long long int | unsigned long long int | long long int* | ||||
| j | intmax_t | uintmax_t | intmax_t* | ||||
| z | size_t | size_t | size_t* | ||||
| t | ptrdiff_t | ptrdiff_t | ptrdiff_t* | ||||
| L | long double | ||||||
#include #include void main()
Форматированный ввод
Рассмотрим форматированный ввод функцией scanf.
int scanf(const char*, . )
Функция принимает строку формата ввода (она похожа на строку формата printf) и адреса, по которым необходимо записать считанные данные. Возвращает количество успешно проинициализированных аргументов.
Формат спецификатора ввода
%[*][ширина][длинна]спецификатор
| Спецификатор | Описание | Выбранные символы |
|---|---|---|
| i, u | Целые | Произвольное число цифр (0-9), возможно, начинающихся с + или -. Если число начинается с 0, то считывается в восьмеричном формате, если с 0x, то в шестнадцатеричном. |
| d | Десятичное целое | Произвольное число цифр (0-9), возможно, начинающихся с + или -. |
| o | восьмеричное целое | Произвольное число цифр (0-7), возможно, начинающихся с + или -. |
| x | Шестнадцатеричное целое | Произвольное число цифр (0-F), возможно, начинающихся с + или – и префикса 0x или 0X. |
| f, e, g | Число с плавающей точкой | Число, состоящее из набора цифр 0-9, возможно с десятичным разделителем (точкой). Возможно также представление в экспоненциальной форме. C99 позволяет также вводить число в шестнадцатеричном формате. |
| a | ||
| c | Символ | Если ширина не передана, то считывает один символ. Если ширина передана, то считывает нужное количество символов и размещает их в массиве БЕЗ терминального символа на конце. |
| s | Строка | Считывает все не пробельные символы. Если указана ширина, то не более n символов. Ставит на место n+1 символа терминальный. |
| p | Адрес указателя | Последовательность символов, трактуемая как адрес указателя. Формат зависит от реализации, но совпадает с тем, как выводит printf с ключом p |
| [символы] | Множество символов | Считывает только те символы, которые записаны в квадратных скобках, С99 |
| [^символы] | Множество символов | Считывает только те символы, которые не указаны в квадратных скобках, С99 |
| n | Ничего не считывает | Сохраняет число уже считанных символов по указанному адресу |
Как и в printf, ширина, заданная символом * ожидает аргумента, который будт задавать ширину. Флаг длина совпадает с таким флагом функции printf.
#include #include void main() < int year, month, day; char buffer[128]; int count; //Требует форматированного ввода, например 2013:12:12 printf("Enter data like x:x:x = "); scanf("%d:%d:%d", &year, &month, &day); printf("year = %d\nmonth = %d, day = %d\n", year, month, day); //Считываем строку, не более 127 символов. При считывании в массив писать & не надо, //так как массив подменяется указателем printf("Enter string = "); scanf("%127s", buffer); printf("%s", buffer); getch(); >
Кроме функций scanf и printf есть ещё ряд функций, которые позволяют получать вводимые данные
int getch() [aka _getch(), getchar()] – возвращает введённый символ, при этом не выводит его на консоль.
#include #include void main() < char c = 0; do < c = getch(); printf("%c", c); >while (c != 'q'); >
char * fgets ( char * str, int num, FILE * stream ) – функция позволяет считывать строку с пробельными символами. Несмотря на то, что она работает с файлом, можно с её помощью считывать и из стандартного потока ввода. Её преимущество относительно gets в том, что она позволяет указать максимальный размер считываемой строки и заканчивает строку терминальным символом.
#include #include #include void main() < char buffer[128]; //Считываем из стандартного потока ввода fgets(buffer, 127, stdin); printf("%s", buffer); //Этим можно заменить ожидание ввода символа scanf("1"); >
Это не полный набор различных функций символьного ввода и вывода. Таких функций море, но очень многие из них небезопасны, поэтому перед использованием внимательно читайте документацию.
Непечатные символы
В си определён ряд символов, которые не выводятся на печать, но позволяют производить форматирование вывода. Эти символы можно задавать в виде численных значений, либо в виде эскейп-последовательностей: символа, экранированного обратным слешем.
| Последовательность | Числовое значение | Результат |
|---|---|---|
| \a | 0x07 | Звуковой сигнал |
| \b | 0x08 | Перевод каретки на одно значение назад |
| \f | 0x0c | Новая страница |
| \n | 0x0a | Перевод строки, новая строка |
| \r | 0x0d | Возврат каретки |
| \t | 0x09 | Табуляция |
| \v | 0x0b | Вертикальная табуляция |
| \” | 0x22 | Двойная кавычка |
| \\ | 0x5с | Обратный слеш |
#include #include void main() < char backspace = 0x08; //Выводим с использованием символа переноса строки printf("Hello\nWorld\n"); //Выводим символ переноса строки через его значение printf("Hello%cWorld\n", 0x0a); //"Выводим" сигнал printf("\a"); //Выводим сигнал, как символ printf("%c", '\a'); //Выводим сигнал через шестнадцатеричное значение printf("%c", 0x07); printf("This is sparta. \b\b%c", backspace); printf(" "); getch(); >
YAML за 5 минут: синтаксис и основные возможности
YAML — это язык для сериализации данных, который отличается простым синтаксисом и позволяет хранить сложноорганизованные данные в компактном и читаемом формате. Рассказываем, как это пригодится для DevOps и виртуализации.
- Что такое YAML?
- YAML vs JSON vs XML
- Характерные особенности YAML
- Синтаксис YAML
- Что ещё может YAML?
Что такое YAML?
YAML — это язык для хранения информации в формате понятном человеку. Его название расшифровывается как, «Ещё один язык разметки». Однако, позже расшифровку изменили на — «YAML не язык разметки», чтобы отличать его от настоящих языков разметки.
Язык похож на XML и JSON, но использует более минималистичный синтаксис при сохранении аналогичных возможностей. YAML обычно применяют для создания конфигурационных файлов в программах типа Инфраструктура как код (Iac), или для управления контейнерами в работе DevOps.
Чаще всего с помощью YAML создают протоколы автоматизации, которые могут выполнять последовательности команд записанные в YAML-файле. Это позволяет вашей системе быть более независимой и отзывчивой без дополнительного внимания разработчика.
DevOps-инженер (Мой МТС СНГ) МТС , Москва, можно удалённо , По итогам собеседования
Всё больше и больше компаний используют DevOps и виртуализацию, поэтому YAML — это must have для современного разработчика. Кроме того, YAML легко интегрировать, благодаря поддержке Python (используя PyYAML библиотеку, Docker или Ansible) и других популярных технологий.
YAML vs JSON vs XML
YAML (.yml)
- понятный человеку код;
- минималистичный синтаксис;
- заточен под работу с данными;
- встроенный стиль, похожий на JSON (YAML является его надмножеством);
- поддерживает комментарии;
- поддерживает строки без кавычек;
- считается «чище», чем JSON;
- дополнительные возможности (расширяемые типы данных, относительные якоря и маппинг типов с сохранением порядка ключей).
Применение: YAML лучше всего подходит для приложений с большим объемом данных, которые используют DevOps конвейеры или виртуальные машины. Кроме того, улучшение читаемости данных пригодится в командах, где разработчики часто с ними взаимодействуют.
JSON
- труднее читать;
- явные, строгие требования к синтаксису;
- встроенный стиль, похожий на YAML (некоторые парсеры YAML могут читать JSON-файлы);
- нет комментариев;
- строкам нужны двойные кавычки.
Применение: JSON используется в веб-разработке — это лучший формат для сериализации и передачи данных через HTTP-соединение.
XML
- труднее читать;
- более многословный;
- действует как язык разметки, а YAML как язык для форматирования данных;
- больше возможностей чем у YAML, например атрибуты тегов;
- более жёсткая схема документа.
Применение: XML идеален для сложных проектов, которым требуется тонкий контроль над валидацией, схемой и пространством имён. Язык обладает плохой читаемостью, требует большей пропускной способности и ёмкости хранилища, но обеспечивает беспрецедентный контроль.
Характерные особенности YAML
Поддержка мультидокументов
Вы можете объединить несколько YAML-документов в один YAML-файл для облегчения организации файлов и парсинга данных.
Документы разделяются тремя дефисами (—):
--- player: playerOne action: attack (miss) --- player: playerTwo action: attack (hit) ---
Поддержка комментариев
YAML позволяет добавлять комментарии после символа #, как в Python:
key: #Это однострочный комментарий - value line 5 #Это #многострочный комментарий - value line 13
Легко читаемый синтаксис
В синтаксисе YAML-файлов используется система отступов, как в Python. Необходимо использовать пробелы, а не табуляцию, чтобы избежать путаницы.
Это избавляет от лишних символов, которые есть в JSON и XML (кавычки, скобки, фигурные скобки).
В итоге читаемость файла значительно повышается.
YAML
#YAML Imaro: author: Charles R. Saunders language: English publication-year: 1981 pages: 224
JSON
Явная и неявная типизация
YAML предлагает как автоопределение типов, так и возможность явно указать тип данных. Чтобы использовать конкретный тип, нужно написать !![тип] перед значением.
# Это значение преобразуется в int: is-an-int: !!int 14.10 # Превращает любое значение в строку: is-a-str: !!str 67.43 # Значение должно быть boolean: is-a-bool: !!bool yes
Отсутствие исполняемых файлов
YAML не содержит исполняемых файлов. Поэтому можно безопасно обмениваться YAML-файлами с третьей стороной.
Чтобы использовать исполняемые файлы, YAML нужно интегрировать с другими языками, например Perl или Java.
Синтаксис YAML
В языке есть несколько базовых концепций, которые позволяют обрабатывать большинство данных.
Пары ключ-значение
Большинство данных в YAML-файле хранятся в виде пары ключ-значение, где ключ — это имя пары, а значение — связанные данные.
Скаляры и маппинг
Скаляр представляет собой одно значение, которому соответствует имя.
YAML поддерживает стандартные типы: int и float, boolean, string и null.
Они могут быть представлены в разных видах: шестнадцатеричном, восьмеричном или экспоненциальном. Также существуют специальные типы для математических сущностей, такие как: бесконечность, -бесконечность и NAN.
integer: 25 hex: 0x12d4 #равно 4820 octal: 023332 #равно 9946 float: 25.0 exponent: 12.3015e+05 #равно 1230150.0 boolean: Yes string: "25" infinity: .inf # преобразуется в бесконечность neginf: -.Inf #преобразуется в минус бесконечность not: .NAN #Not a Number null: ~
Строки
Строка — это коллекция символов, которая может содержать слово или предложение. Можно использовать либо |, для отдельных строк, либо >, для параграфов.
Кавычки в YAML не нужны.
str: Hello World data: | Это Отдельные Строки data: > Это один параграф текста
Последовательности
Последовательности — это структуры данных похожие на списки или массивы, которые хранят несколько значений под одним ключом. Они определяются с помощью отступов или [].
shopping: - milk - eggs - juice
Однострочные последовательности выглядят лаконичнее, но хуже читаются.
shopping: [milk, eggs, juice]
Словари
Словари — это коллекции пар ключ-значение, которые хранятся под одним ключом. Они позволяют разделить данные на логические категории.
Employees: - dan: name: Dan D. Veloper job: Developer team: DevOps - dora: name: Dora D. Veloper job: Project Manager team: Web Subscriptions
Словари могут содержать более сложные структуры, что позволяет хранить сложные реляционные данные.
Что ещё может YAML?
- Anchors (якоря)
- Templates (шаблоны)
- Взаимодействие с Docker, Ansible и т. д.
- Расширенные последовательности и маппинг.
- Расширенные типы данных (timestamp, null и т. д.)
Comments are closed, but trackbacks and pingbacks are open.