cpp

Форматированный вывод данных

Для форматированного вывода используется функция Printf() из пакета fmt. Формат функции:

fmt.Printf(format string, a ...interface{}) (n int, err error)

В параметре format указывается строка специального формата. Внутри этой строки можно указать обычные символы и спецификаторы формата, начинающиеся с символа %. Вместо спецификаторов формата подставляются значения, указанные в качестве параметров. Количество спецификаторов должно совпадать с количеством переданных параметров. Пример вывода строки и числа:

fmt.Printf("String\n")
fmt.Printf("Count %d\n", 10)
fmt.Printf("%s %d\n", "Count", 10)

Результат выполнения:

String
Count 10
Count 10

В первом примере строка формата не содержит спецификаторов и выводится как есть. Во втором примере внутри строки формата используется спецификатор %d, предназначенный для вывода целого числа. Вместо этого спецификатора подставляется число 10, переданное во втором параметре. В третьем примере строка содержит сразу два спецификатора %s и %d. Спецификатор %s, предназначен для вывода строки, а спецификатор %d — для вывода целого числа. Вместо спецификатора %s будет подставлена строка Count, а вместо спецификатора %d — число 10.

Функция Printf() возвращает два значения. Первое значение содержит количество байтов, записанных в поток. Через второе значение можно получить сообщение об ошибке. Если ошибка не возникла, то значением будет nil:

n, err := fmt.Printf("строка")  // строка
fmt.Println(n, err)             // 12 <nil>

Спецификаторы имеют следующий синтаксис:

%[<Флаги>][<Ширина>][.<Точность>][<Размер>]<Тип>

В параметре <Тип> могут быть указаны следующие символы:

  • v — позволяет вывести данные любого типа с форматированием по умолчанию:
fmt.Printf("%v %v %v %v\n", true, 10, 14.5, "строка")
// true 10 14.5 строка

При выводе структуры по умолчанию отображаются только значения через пробел внутри фигурных скобок. Чтобы дополнительно отобразить названия полей, следует использовать спецификатор %+v. Чтобы дополнительно вывести название структуры можно воспользоваться спецификатором %#v:

type Point struct {
   X, Y int
}
p := Point{10, 20}
fmt.Printf("%v\n", p)    // {10 20}
fmt.Printf("%+v\n", p)   // {X:10 Y:20}
fmt.Printf("%#v\n", p)   // main.Point{X:10, Y:20}

Спецификатор %#v можно также использовать для детального вывода данных других типов, например, массивов:

arr := [2]int{10, 20}
fmt.Printf("%v\n", arr)  // [10 20]
fmt.Printf("%#v\n", arr) // [2]int{10, 20}
  • t — логическое значение:
fmt.Printf("%t %t\n", true, 10 == 5) // true false
  • c — символ:
fmt.Printf("%c", 'w')              // w
fmt.Printf("%c", 119)              // w

Если нужно вывести символ внутри одинарных кавычек с экранированием специальных символов, то следует воспользоваться спецификатором %q:

fmt.Printf("%q", 119)              // 'w'
fmt.Printf("%q", 10)               // '\n'
  • U — вывод кода символа в формате Unicode:
fmt.Printf("%U\n", 10)             // U+000A
fmt.Printf("%U\n", 119)            // U+0077
fmt.Printf("%U\n", 'w')            // U+0077
fmt.Printf("%#U\n", 'w')           // U+0077 'w'
  • s — строка:
fmt.Printf("%s\n", "String")       // String
fmt.Printf("%s", []byte("String")) // String
  • q — строка в двойных кавычках с экранированием специальных символов:
fmt.Printf("%q", "String\n\t")     // "String\n\t"
  • d — десятичное целое число со знаком:
fmt.Printf("%d %d", 10, -30)       // 10 -30
  • b — двоичное представление числа:
fmt.Printf("%b\n", 100)            // 1100100
fmt.Printf("%#b", 100)             // 0b1100100
  • o и O —восьмеричное представление числа:
fmt.Printf("%o %o\n", 10, 0o77)    // 12 77
fmt.Printf("%#o %#o\n", 10, 077)   // 012 077
fmt.Printf("%O %O", 10, 0o77)      // 0o12 0o77
  • x — шестнадцатеричное число в нижнем регистре:
fmt.Printf("%x %x\n", 10, 0xff)    // a ff
fmt.Printf("%#x %#x", 10, 0xff)    // 0xa 0xff
  • X — шестнадцатеричное число в верхнем регистре:
fmt.Printf("%X %X\n", 10, 0xff)    // A FF
fmt.Printf("%#X %#X", 10, 0xff)    // 0XA 0XFF
  • f и F — вещественное число в десятичном представлении:
fmt.Printf("%f %f\n", 18.65781452, 12.5) // 18.657815 12.500000
fmt.Printf("%F %F\n", 18.65781452, 12.5) // 18.657815 12.500000
fmt.Printf("%f\n", -18.65781452)         // -18.657815
fmt.Printf("%#.0f %.0f", 100.0, 100.0)   // 100. 100
  • e — вещественное число в экспоненциальной форме (буква «e» в нижнем регистре):
fmt.Printf("%e\n", 18657.81452) // 1.865781e+04
fmt.Printf("%e", 0.000081452)   // 8.145200e-05
  • E — вещественное число в экспоненциальной форме (буква «e» в верхнем регистре):
fmt.Printf("%E", 18657.81452)   // 1.865781E+04
  • g — эквивалентно f или e (выбирается более короткая запись числа):
fmt.Printf("%g %g %g", 0.086578, 0.000086578, 1.865E-005)
// 0.086578 8.6578e-05 1.865e-05
  • G — эквивалентно f или E (выбирается более короткая запись числа):
fmt.Printf("%G %G %G", 0.086578, 0.000086578, 1.865E-005)
// 0.086578 8.6578E-05 1.865E-05
  • p — вывод адреса переменной:
x := 10
fmt.Printf("%p", &x) // 0xc000012088
  • T — вывод типа переменной:
x := 10
fmt.Printf("%T", x)  // int
  • % — символ процента (%):
fmt.Printf("10%%")   // 10%

Параметр <Ширина> задает минимальную ширину поля. Если строка меньше ширины поля, то она дополняется пробелами. Если строка не помещается в указанную ширину, то значение игнорируется и строка выводится полностью:

fmt.Printf("'%3s'", "string")  // 'string'
fmt.Printf("'%10s'", "string") // '    string'

Задать минимальную ширину можно не только для строк, но и для других типов:

fmt.Printf("'%10d'", 25)       // '        25'
fmt.Printf("'%10f'", 12.5)     // ' 12.500000'

Параметр <Точность> задает количество знаков после точки для вещественных чисел. Перед этим параметром обязательно должна стоять точка:

fmt.Printf("'%10.5f'", 3.14159265359) // '   3.14159'
fmt.Printf("'%.3f'", 3.14159265359)   // '3.142'

Если параметр <Точность> используется применительно к целому числу, то он задает минимальное количество цифр. Если число содержит меньшее количество цифр, то вначале числа добавляются нули:

fmt.Printf("'%7d'", 100)              // '    100'
fmt.Printf("'%.7d'", 100)             // '0000100'
fmt.Printf("'%.7d'", 123456789)       // '123456789'

Если параметр <Точность> используется применительно к строке, то он задает максимальное количество символов. Символы, которые не помещаются, будут отброшены:

fmt.Printf("'%5.7s'", "Hello, world!")   // 'Hello, '
fmt.Printf("'%5.7s'", "Привет, мир!")    // 'Привет,'
fmt.Printf("'%15.20s'", "Hello, world!") // '  Hello, world!'

Вместо минимальной ширины и точности можно указать символ *. В этом случае значения передаются через параметры в порядке указания символов в строке формата:

fmt.Printf("'%*.*f'", 10, 5, 3.14159265359) // '   3.14159'
fmt.Printf("'%.*f'", 3, 3.14159265359)      // '3.142'
fmt.Printf("'%*s'", 10, "string")           // '    string'

В первом примере вместо первого символа * подставляется число 10, указанное во втором параметре, а вместо второго символа * подставляется число 5, указанное в третьем параметре. Во втором примере вместо символа * подставляется число 3, которое задает количество цифр после точки. В третьем примере символ * заменяется числом 10, которое задает минимальную ширину поля.

В параметре <Флаги> могут быть указаны следующие символы:

  • # — для двоичных значений добавляет комбинацию символов 0b, для восьмеричных значений добавляет в начало символ 0, для шестнадцатеричных значений добавляет комбинацию символов 0x (если используется тип x) или 0X (если используется тип X), для вещественных чисел указывает всегда выводить дробную точку, даже если задано значение 0 в параметре <Точность>:
fmt.Printf("%#b\n", 100)               // 0b1100100
fmt.Printf("%#o %#o\n", 10, 077)       // 012 077
fmt.Printf("%#x %#x\n", 10, 0xff)      // 0xa 0xff
fmt.Printf("%#X %#X\n", 10, 0xff)      // 0XA 0XFF
fmt.Printf("%#.0f %.0f", 100.0, 100.0) // 100. 100
  • 0 — задает наличие ведущих нулей для числового значения:
fmt.Printf("'%7d'", 100)               // '    100'
fmt.Printf("'%07d'", 100)              // '0000100'
  • - — задает выравнивание по левой границе области. По умолчанию используется выравнивание по правой границе:
fmt.Printf("'%5d' '%-5d'", 3, 3)       // '    3' '3    '
  • пробел — вставляет пробел перед положительным числом. Перед отрицательным числом будет стоять минус:
fmt.Printf("'% d' '% d'", -3, 3)       // '-3' ' 3'
  • + — задает обязательный вывод знака, как для отрицательных, так и для положительных чисел:
fmt.Printf("'%+d' '%+d'", -3, 3)       // '-3' '+3'

По умолчанию используется позиционное присваивание. Это поведение можно изменить, указав индекс значения (нумерация с 1) внутри квадратных скобок:

fmt.Printf("%[2]d %[1]d %[1]d\n", 10, 20)              // 20 10 10
fmt.Printf("'%[3]*.[2]*[1]f'\n", 3.14159265359, 5, 10) // '   3.14159'

Последняя инструкция эквивалента следующей:

fmt.Printf("'%*.*f'", 10, 5, 3.14159265359)            // '   3.14159'

Если выводить несколько значений подряд с помощью функции Printf(), то они все отобразятся на одной строке:

fmt.Printf("string1")
fmt.Printf("string2")
// string1string2

Чтобы значения выводились на отдельных строках нужно воспользоваться комбинацией символов \n, обозначающей перевод строки:

fmt.Printf("string1\n")
fmt.Printf("string2")
/*
string1
string2 */

Для форматированного вывода в указанный поток можно воспользоваться функцией Fprintf() из пакета fmt. Формат функции:

fmt.Fprintf(w io.Writer, format string,
            a ...interface{}) (n int, err error)

В первом параметре указывается поток вывода. Это может быть файл или стандартный поток вывода (os.Stdout или os.Stderr). Во втором параметре передается строка формата, внутри которой можно использовать те же самые спецификаторы, что и в функции Printf(). В последующих параметрах передаются выводимые значения. Пример вывода сообщения в стандартный поток вывода:

// import "os"
fmt.Fprintf(os.Stdout, "%s %d\n", "x =", 10)  // x = 10

Теперь выведем сообщение в стандартный поток ошибок:

fmt.Fprintf(os.Stderr, "Сообщение об ошибке") // Сообщение об ошибке

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp