Fprintf форматный вывод в файл


Содержание

Ввод данных из файла и вывод в файл

Открытие и закрытие файлов

До этого при вводе-выводе данных мы работали со стандартными потоками — клавиатурой и монитором. Теперь рассмотрим, как в языке C реализовано получение данных из файлов и запись их туда. Перед тем как выполнять эти операции, надо открыть файл и получить доступ к нему.

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:
FILE *myfile;

С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения («r»), записи («w») или добавления («a») и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:
myfile = fopen («hello.txt», «r»);

При чтении или записи данных в файл обращение к нему осуществляется посредством файлового указателя (в данном случае, myfile).

Если в силу тех или иных причин (нет файла по указанному адресу, запрещен доступ к нему) функция fopen() не может открыть файл, то она возвращает NULL. В реальных программах почти всегда обрабатывают ошибку открытия файла в ветке if , мы же далее опустим это.

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

После того, как работа с файлом закончена, принято его закрывать, чтобы освободить буфер от данных и по другим причинам. Это особенно важно, если после работы с файлом программа продолжает выполняться. Разрыв связи между внешним файлом и указателем на него из программы выполняется с помощью функции fclose() . В качестве параметра ей передается указатель на файл:
fclose(myfile);

В программе может быть открыт не один файл. В таком случае каждый файл должен быть связан со своим файловым указателем. Однако если программа сначала работает с одним файлом, потом закрывает его, то указатель можно использовать для открытия второго файла.

Чтение из текстового файла и запись в него

fscanf()

Функция fscanf() аналогична по смыслу функции scanf() , но в отличии от нее осуществляет форматированный ввод из файла, а не стандартного потока ввода. Функция fscanf() принимает параметры: файловый указатель, строку формата, адреса областей памяти для записи данных:
fscanf (myfile, «%s%d», str, &a);

Возвращает количество удачно считанных данных или EOF. Пробелы, символы перехода на новую строку учитываются как разделители данных.

Допустим, у нас есть файл содержащий такое описание объектов:

Тогда, чтобы считать эти данные, мы можем написать такую программу:

В данном случае объявляется структура и массив структур. Каждая строка из файла соответствует одному элементу массива; элемент массива представляет собой структуру, содержащую строковое и два числовых поля. За одну итерацию цикл считывает одну строку. Когда встречается конец файла fscanf() возвращает значение EOF и цикл завершается.

fgets()

Функция fgets() аналогична функции gets() и осуществляет построчный ввод из файла. Один вызов fgets() позволят прочитать одну строку. При этом можно прочитать не всю строку, а лишь ее часть от начала. Параметры fgets() выглядят таким образом:
fgets ( массив_символов, количество_считываемых_символов, указатель_на_файл )

Например:
fgets (str, 50, myfile)

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа ‘\n’, который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ ‘\0’, добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет ‘\0’. В таком случае ‘\n’ в считанной строке содержаться не будет.

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

Ниже приводятся примеры кода, в которых используются три способа вывода данных в файл.

Запись в каждую строку файла полей одной структуры:

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки ‘\n’):

Пример посимвольного вывода:

Чтение из двоичного файла и запись в него

С файлом можно работать не как с последовательностью символов, а как с последовательностью байтов. В принципе, с нетекстовыми файлами работать по-другому не возможно. Однако так можно читать и писать и в текстовые файлы. Преимущество такого способа доступа к файлу заключается в скорости чтения-записи: за одно обращение можно считать/записать существенный блок информации.

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка «rb» или «wb».

Тема о работе с двоичными файлами достаточно сложная, для ее изучения требуется отдельный урок. Здесь будут отмечены только особенности функций чтения-записи в файл, который рассматривается как поток байтов.

Функции fread() и fwrite() принимают в качестве параметров:

  1. адрес области памяти, куда данные записываются или откуда считываются,
  2. размер одного данного какого-либо типа,
  3. количество считываемых данных указанного размера,
  4. файловый указатель.

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно «заказать» считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.

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

3 Bruce [2011-12-06 03:35:00]

Я написал эту небольшую программу C:

Затем я проанализировал data.txt с помощью xxd -b . Я ожидал, что увижу 32-битное представление 578 вместо этого, я увидел ASCII-представление 578:

Почему? Как сохранить 32-битное представление 578 (01000010 00000010 00000000 00000000), если предположить, что он немного endian?

4 ответа

5 Решение Kerrek SB [2011-12-06 03:38:00]

fprintf предназначен для форматированного вывода, откуда находится конечный f .

Это значение «Отформатировано». Вы использовали квалификатор %d , который означает «отформатируйте данное значение как числовое представление ASCII в наборе символов выполнения, предполагая, что это целое число со знаком».

Если вы хотите записать двоичные данные в файл — не, используйте форматированный вывод. Используйте fwrite вместо того, чтобы писать сырые двоичные данные.

1 abelenky [2011-12-06 03:38:00]

Вы хотите посмотреть fwrite.

1 sarnold [2011-12-06 03:45:00]

Если вы хотите записать необработанные данные в файл с помощью стандартных объектов ввода-вывода, вы ищете fwrite(3) :

Printf C: описание, форматирование, примеры

Стандартная функция консольного вывода в языке C – printf. Описание её содержится в заголовочном файле stdio.h. При помощи этой функции можно выводить данные или пользовательские сообщения в консоль. Язык C чувствителен к регистру. К примеру, две функции printf и scanf отличаются от подобных им Printf и Scanf. Все символы в функциях printf и scanf также должны быть записаны в нижнем регистре. Одним из простейших примеров C printf, выводящим на экран знакомое приветствие hello world, является:

Определение функций группы printf в файле «stdio.h»

Файл «stdio.h» относится к стандартной библиотеке ввода/вывода в языке С. Описание printf и подобных ей функций приводится в нём следующим образом:

Перечисленные функции производят загрузку данных из определённых локаций, преобразовывают их в символьную строку, отправляют в заданные потоки вывода.

Семейство функций printf

Функции группы printf в языке C служат для обработки и форматированного вывода данных в стандартный поток. Причём функции printf и vprintf производят запись в стандартный поток stdout, функции fprintf и vfprintf отправляют значения выводимых аргументов в некоторый заданный выходной поток, а snprintf, sprintf, vsnprintf и vsprintf записывают данные в символьную строку. Все перечисленные функции работают с использованием строки формата, указывающей необходимые преобразования аргументов для вывода.

Функция fprintf записывает результат в выходной поток stream. В буфер, представляющий собой символьную строку, выводит результат функция sprintf. Поведение функции не определено, если подлежащая выводу строка превышает размер массива буфера.

Функция snprintf так же, как и предыдущая, записывает данные в строковый буфер. Полученная строка символов завершается нулевым символом, если только bufsz (размер буфера) не равен нулю. Иначе, если значение bufsz равно нулю, то в буфер ничего не выводится, а сам буфер вполне может являться нулевым указателем, но возвращаемое значение (количество байтов, которое должно было быть записано) все равно вычисляется.

Функция printf_s в целом действует тем же образом, что и printf, за исключением одного момента. Главным отличием в описании printf_s в C и printf является следующее: функция printf_s выполняет проверку строки форматирования на наличие допустимых символов в отличие от printf, которая только проверяет строку формата на предмет пустого указателя.

Подробнее рассмотрим функцию printf.

Общее описание

В языке C печать символов через стандартный поток вывода осуществляется посредством вызова функции printf. Команда printf в C форматирует набор выводимых данных, и они отправляются в стандартный поток вывода stdout. Значения, переданные в качестве аргументов функции, выводятся в консоль согласно указанной строке форматирования, которая в свою очередь заключает в себе две разновидности элементов. Первая разновидность — это символы, выводимые на экран, а элементы, определяющие особенности формата данных и отвечающие за метод представления аргументов при выводе, относятся ко второму виду.

При выводе переменных с printf в C особые комбинации символов в строке аргументов заменяются на преобразованные в соответствии с этими символами данные, причём для каждого типа данных существуют свои спецификации формата вывода.

Тип функции и возвращаемое значение

Функция printf, имеющая тип int, возвращает целочисленную величину, обозначающую количество напечатанных на экране символов. К примеру, можно присвоить:

int k = printf(«Привет %c %d %s», ‘a’, 11, «всем!»),

и тогда по значению переменной k легко определяется, возникла ли ошибка при выводе. В случае возврата отрицательного значения (если функция вернула «-1») можно сделать вывод, что произошла ошибка при её выполнении.

Синтаксис и зависимости

Чтобы использовать функцию printf, требуется подключить заголовочный файл «stdio.h» следующим образом:

Шаблон функции выглядит:

int printf(const char *формат, . )

Под многоточием подразумевается список аргументов, подлежащих выводу. Функция printf может быть использована с различным числом аргументов, но первый из них всегда ограничивается с обеих сторон двойными кавычками, а каждый последующий необходимо отделять от предыдущего запятой. То, что записано в двойных кавычках и при том не является спецификацией формата, печатается без изменений, иначе, если встретился спецификатор, копируется тип его значения.

Форма задания спецификаций формата:

Форматирование с printf в C выходных значений

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

Символ «%» указывает на начало спецификации формата вывода, следом за ним идёт код формата. Все поля в спецификации представляют собой отдельные, определяющие условия форматирования числа или символы.

Форматированный вывод printf в C обладает своими особенностями. В случае, если количество перечисленных аргументов превышает число спецификаций формата, они пропускаются и не выводятся. Иначе, если спецификаций формата больше, чем значений в списке подлежащих печати аргументов, результат вызова функции не определяется.

Для явного указания, который по счёту аргумент нужно задействовать, возможно использовать «%m$» вместо «%» и «*m$» вместо «*», причём m, целочисленное десятичное значение, обозначает позицию нужного аргумента (индексирование начинается с единицы).

Параметры

stream Выходной поток для записи в файл
buffer Указатель на символьную строку для последующей записи в неё
bufsz Определяет число символов, допустимое для записи: максимальное значение — bufsz-1, и ещё нулевой ограничитель
format Указатель на многобайтовую строку с нулевым ограничителем, определяющую, как интерпретировать выводимые аргументы
Флаги, используемые в строке формата
Флаг Описание
Выравнивание результата по левому краю в поле вывода
+ При выводе численного значения, имеющего знак, принудительно печатается «+» перед положительной величиной (по умолчанию выводится только «-» перед отрицательным значением)
Для целых чисел и чисел с плавающей запятой ведущие нули используются вместо символов пробела для заполнения левых разрядов в случае, если задана ширина поля, превышающая длину числа. Для целых чисел флаг игнорируется, если явно указана точность. Для других преобразований с использованием этого флага поведение функции не определено. Флаг «0» не учитывается, если присутствует флаг «-«
space Если результат вывода выражения, имеющего знак, не начинается с символа этого знака или пуст, то пробел добавляется к результату. Флаг «space» игнорируется, если присутствует флаг «+»
# Выполняется альтернативная форма преобразования
Управляющие последовательности
Последовательность Результат
\a Звуковой сигнал
\n Перевод на новую строку
\r Возвращение курсора в начало строки
\t Табуляция
\v Вертикальная табуляция
Вывод двойной кавычки
\\ Вывод косой черты

Различные спецификаторы формата

Спецификатор формата Использование и описание для printf C Тип аргумента
% Запись литерала «%»
c Вывод одного символа. Происходит преобразование аргумента в тип unsigned char. При использовании модификатора «l» аргумент преобразуется в строку символов unsigned char
s Печать строки символов. Аргумент должен являться указателем на начальный элемент массива символов char char *
d
i
Вывод десятичного представления целочисленного значения со знаком int
o Вывод восьмеричного представления без знакового целочисленного значения unsigned int
x
X
Вывод шестнадцатеричного представления без знакового целочисленного значения. Символы «a», «b», «c», «d», «e», «f» применяются для преобразования «x». А для преобразования «X» — «A», «B», «C», «D», «E», «F» unsigned int
u Вывод десятичного преобразования без знакового целочисленного значения. Если преобразованное значение и точность вместе равны 0, то символы не выводятся unsigned int
f
F
Вывод десятичного представления числа с плавающей запятой, имеющего знак double
e
E
Вывод десятичного экспоненциального представления числа с плавающей запятой, округлённого и преобразованного так, что перед запятой остаётся одна цифра, а количество цифр после запятой соответствует точности представления (по умолчанию точность равна 6, а если указан 0, то символ запятой не выводится вообще). Символ «е» выводится в верхнем или нижнем регистре в зависимости от преобразования double
a
A
Вывод шестнадцатеричного представления числа с плавающей запятой double
g
G
Вывод десятичного представления числа с плавающей запятой или его десятичного экспоненциального представления в зависимости от значения и точности double
n Возврат числа элементов, выведенных функцией printf. Результат записывается в переменную, на которую указывает аргумент. Спецификация может не содержать флагов, ширины поля или точности int *
p Вывод указателя void *

Модификатор ширины поля

В строке формата в printf C может быть записано целое число после знака процента и перед командой форматирования. Оно является модификатором ширины поля и влияет на представление отображаемых данных. Наименьшая ширина поля, предназначенная для значения, определяется этим числом, и присутствие такого модификатора в случае, если аргумент оказывается меньше выделенного ему поля, вызывает добавление к результату пробелов или нулей. Заполнителем по умолчанию служит символ пробела, однако можно установить ноль, прописав его перед спецификацией ширины. Модификатор указывает минимум ширины, и любое превышающее этот минимум значение будет напечатано без помех. Число, к примеру, состоящее менее чем из восьми символов и печатаемое со спецификацией «%08d», окажется дополненным до необходимых восьми знаков нулями.

Подобные модификаторы могут также задавать параметры точности или выравнивания.

Модификатор точности

Модификатор точности служит для определения числа печатаемых десятичных знаков в представлении чисел. Для добавления модификатора точности необходимо поставить точку после спецификации ширины поля и указать нужное значение точности после неё. Модификатор точности определяется для «e», «f», «a», «E», «A» и «F» форматов. Для целых чисел модификатор устанавливает количество отображаемых цифр, добавляя нули в левый разряд, если нужно, а при выводе рациональных чисел определяет необходимое количество знаков после запятой. Применительно к строковым переменным: следующее после точки число в модификаторе точности служит определителем максимальной длины поля при выводе. К примеру, при заданной спецификации формата «%4.8s» будет выведена строка, длина которой находится в диапазоне от четырёх до восьми символов, в случае превышения крайние символы будут опущены.

Илон Маск рекомендует:  Что такое код swfdisplayitem >setdepth

Другие модификаторы формата

Выравниванием по умолчанию является выравнивание по правому краю, однако это можно изменить, поставив знак «-» после «%». Такая спецификация формата устанавливает выравнивание по левому краю.

Кроме того, функция printf способна различать короткие и длинные типы выводимых целых значений. Допустимые спецификаторы: «о», «d», «u», «i», «x» и «X». Длинный тип значения устанавливается модификатором «l», а короткий – модификатором «h». Например, при выводе длинного целого числа и значения типа short unsigned int спецификации формата выглядят как «%ld» и «%hu» соответственно.

Длина Описание
h Для типов short или unsigned short
l Для типов long или unsigned long
L Для типа long double

Примеры

1. Описание printf C и результаты вызова каждой функции:

2. Вывод на экран простого диалогового сообщения:

3. Программный код:

Выражения, заданные в двойных кавычках перед спецификациями формата, печатаются на экране, также как и следующие за строкой формата аргументы. Результат выполнения приведённых выше функций printf C, описание выходных данных:

Данный пример иллюстрирует вывод на экран при помощи различных форматов строк, целочисленных переменных, символов, а также чисел с плавающей точкой.

Diplom Consult.ru

Пример 1: Записать в текстовый файл числа от 0 до 1000 кратные 3.

int _tmain(int argc, _TCHAR* argv[])

if(!(f = fopen(«test.txt», «w+t»)))

printf(«Невозможно создать файл\n»); return 0;

int _tmain(int argc, _TCHAR* argv[])

printf(«\n Введите три оценки, полученные на экзаменах: «);

break; /* Если не удалось прочитать необходимое

количество байт, то заканчиваем чтение */

printf(«%s %d %d %d \n», inf.name, inf.mark[0], inf.mark[1], inf.mark[2]);

Важно понимать, что нет однозначного метода, который можно было бы использовать для отличия текстового файла от бинарного, поэтому любой бинарный файл может быть открыт для работы с ним как с текстовым; а текстовый может быть открыт как бинарный. Но такой вариант работы с файлом обычно приводит к ошибкам. Поэтому рекомендуется работать с конкретным файлом в том режиме, в котором он был создан.

Позиционирование в файле. Каждый открытый файл имеет, так называемыйуказатель на текущую позицию в файле (это нечто подобное указателю в памяти). Все операции над файлами (чтение и запись) работают с данными с этой позиции. При каждом выполнении функции чтения или записи указатель смещается на количество прочитанных или записанных байт, т.е. устанавливается сразу за прочитанным или записанным блоком данных в файле. В этом случае осуществляется так называемыйпоследовательный доступк данным, который очень удобен, когда нам необходимо последовательно работать с данными в файле. Это демонстрируется во всех вышеприведенных примерах чтения и записи в файл. Но иногда необходимо читать или писать данные в произвольном порядке, что достигается путем установки указателя на некоторую заданную позицию в файле функциейfseek().

Разница между fprintf, printf и sprintf?

кто-нибудь может объяснить на простом английском языке о различиях между printf , fprintf и sprintf с примерами?

Я действительно запутался между тремя из них, читая о «обработке файлов в C».

8 ответов

в C «поток» является абстракцией; с точки зрения программы это просто производитель (входной поток) или потребитель (выходной поток) байтов. Он может соответствовать файлу на диске, трубе, терминалу или другому устройству, такому как принтер или tty. The FILE type содержит информацию о потоке. Обычно вы не связываетесь с FILE содержимое объекта напрямую, вы просто передаете указатель на него различным процедурам ввода-вывода.


есть три стандартные потоки: stdin — это указатель на стандартный входной поток, stdout является указателем на стандартный выходной поток и stderr указатель на стандартный поток вывода ошибок. В интерактивном сеансе эти три обычно ссылаются на вашу консоль, хотя вы можете перенаправить их на другие файлы или устройства:

в этом примере stdin Теперь указывает на inputfile.dat , stdout указывает на output.txt и stderr указывает на errors.txt .

fprintf записывает форматированный текст в указанный поток вывода.

printf эквивалентно записи fprintf(stdout, . ) и записывает форматированный текст туда,куда указывает стандартный выходной поток.

sprintf записывает форматированный текст в массив char , в отличие от потока.

printf выходы в стандартный выходной поток ( stdout )

fprintf переходит к дескриптору файла ( FILE* )

sprintf переходит к буферу, который вы выделили. ( char* )

printf(«формат», args) используется для печати данных на стандартный вывод, который часто является монитором компьютера.

sprintf(char *, «format», args) похоже на printf. Вместо отображения формированной строки на стандартном выходе, т. е. мониторе, он хранит формированные данные в строке, на которую указывает указатель char (самый первый параметр). Расположение строки-единственное различие между printf и sprint синтаксис.

fprintf(файл *fp, «формат», args) снова похож на printf. Здесь вместо отображения данных на мониторе или сохранения их в какой-либо строке формируемые данные сохраняются в файле, на который указывает указатель файла, который используется в качестве первого параметра fprintf. Указатель файла является единственным дополнением к синтаксису printf.

Если стандартный вывод файл используется в качестве первого параметра в fprintf, затем рассматривается его работа эквивалентно printf.

printf(. ) эквивалентно fprintf(stdout. ) .

fprintf используется для вывода в поток.

sprintf(buffer. ) используется для форматирования строки в буфер.

обратите внимание, что есть также vsprintf , vfprintf и vprintf

вы также можете делать очень полезные вещи с функцией vsnprintf ():

Функции форматного вывода и ввода printf и scanf

Функция printf стандартной библиотеки предназначена для форматного вывода данных и имеет следующий прототип:

Функция printf преобразует, форматирует и печатает свои аргументы arg1, arg2 и т.д. в стандартном выводе (обычно на экране) в соответствии с информацией, заданной аргументом format, и возвращает количество напечатанных символов.

Форматная строка format содержит два вида объектов: обычные символы, которые непосредственно копируются в выходной поток, и спецификации преобразования, каждая из которых вызывает преобразование и печать очередного аргумента функции printf. Любая спецификация преобразования начинается знаком % и заканчивается символом-спецификатором. Между знаком % и символом-спецификатором могут быть расположены (в указанном ниже порядке) следующие элементы:

· Знак минус, предписывающий «прижать» преобразованный аргумент к левому краю поля.

· Число, задающее минимальную ширину поля. Преобразованный аргумент будет занимать поле по крайней мере указанной ширины. При необходимости лишние позиции слева (или справа при левостороннем выравнивании) будут заполнены пробелами.

· Точка, отделяющая ширину поля от величины, устанавливающей точность.

· Число (точность), задающее максимальное количество печатаемых символов строки, или количество цифр после десятичной точки – для плавающего значения, или минимальное количество цифр – для целого значения.

· Буква h, если печатаемое целое должно рассматриваться как short, или l (латинская буква «эль»), если целое должно рассматриваться как long.

Перечень символов-спецификаторов и задаваемые ими преобразования вывода

Символ-спецификатор Тип аргумента Вид печати
d, i int Десятичное целое
O int Беззнаковое восьмеричное целое (без ведущего нуля)
x, X int Беззнаковое шестнадцатиричное целое (без ведущих и ), для 10,11, … ,15 используются abcdef или ABCDEF
u int Беззнаковое десятичное целое
C int Одиночный символ
S char * Печатаются символы, расположенные до нуль-символа (‘\0’), или в количестве, заданном точностью
F double [ — ]m.dddddd, где количество цифр d задается точностью (по умолчанию равно 6)
e, E double [ — ]m.dddddde±xx или [ — ]m.ddddddE±xx, где количество цифр d задается точностью (по умолчанию равно 6)
g, G double Применяется %e или %E, если порядок меньше, чем -4, или больше или равен точности; в противном случае применяется %f. «Хвостовые» нули и «хвостовая» десятичная точка не печатаются
P void * Указатель (представление зависит от реализации)
% Печатается знак %

Функция scanf стандартной библиотеки предназначена для форматного ввода данных и имеет следующий прототип:

Функция scanf читает символы из стандартного входного потока (обычно с клавиатуры), интерпретирует их согласно спецификациям строки format и рассылает результаты в свои аргументы arg1, arg2 и т.д. Эти аргументы, каждый из которых должен быть указателем, определяют, где будут запоминаться должным образом преобразованные данные.

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

Строка format, управляющая преобразованиями ввода, может включать в себя следующие элементы:

· Пробелы или табуляции, которые игнорируются.

· Обычные литеры (исключая %), которые, как ожидается, совпадут с очередными непробельными символами входного потока.

· Спецификации преобразования, каждая из которых начинается со знака % и завершается символом-спецификатором типа преобразования. В промежутке между ними могут располагаться, причем в указанном здесь порядке: знак * (признак подавления присваивания); число, определяющее ширину поля; буква h, l или L, указывающая на размер получаемого значения.

Перечень символов-спецификаторов и задаваемые ими преобразования ввода

Символ-спецификатор Вводимые данные Тип аргумента
D Десятичное целое int *
I Целое, которое может быть восьмеричным (с ведущим ) или шестнадцатиричным (с ведущими или ) int *
O Восьмеричное целое (с ведущим нулем или без него) int *
u Беззнаковое десятичное целое unsigned int *
X Шестнадцатиричное целое (с ведущими или или без них) int *
C Следующие символы ввода (по умолчанию один) размещаются в указанном месте. Пробельные символы не пропускаются; чтобы прочесть очередной символ, отличный от пробельного, используйте %1s char *
S Строка символов (без обрамляющих кавычек). Завершающий нуль-символ (‘\0’) будет добавлен char *
e, f, g Число с плавающей точкой, возможно со знаком; обязательно присутствие либо десятичной точки, либо экспоненциальной части, а возможно, и обеих вместе float *
% Сам знак %, никакое присваивание не выполняется

Перед символами-спецификаторами d, i, o, u, x может стоять буква h, указывающая на то, что соответствующий аргумент должен иметь тип short * (а не int *), или l (латинская «эль»), указывающая на тип long *. Аналогично, перед символами-спецификаторами e, f, g может стоять буква l, указывающая, что тип аргумента – double * (а не float *).

Тема 11. Файлы

Для работы с файлом нужно сначала объявить указатель файла, который будет в дальнейшем использоваться для непосредственной работы с файлом:

где FILE — имя типа по аналогии с char, int, float, double; fp — переменная-указатель на файл.

Далее нужно открыть файл, т.е. связать указатель файла с конкретным файлом, который или уже существует или будет создаваться. Для этого используется функция fopen( , ), например:

fp = fopen(«myFile1», «w»);

Здесь «myFile1» — имя файла, «w» — режим использования файла. Возможны следующие режимы:

«r» — чтение существующего файла;

«w» — запись в файл (если он существует, то его содержимое уничтожается; если файл

отсутствует, то он будет создан;

«a» — добавление в конец файла (если файл отсутствует, то он будет создан).

Чтобы выполнялись и чтение и запись нужно в стринг режима добавить знак «+». Для бинарных (двоичных) файлов в стринг режима нужно добавить букву «b», а для текстовых файлов — букву «t» (последнее подразумевается по умолчанию).

Теперь можно работать с файлом с помощью библиотечных функций fscanf и fprintf. Эти функции аналогичны функциям scanf и printf и отличаются тем, что ввод/вывод данных, связанный с консолью, теперь перенаправляется в файл, для чего в эти функции добавлен еще один аргумент — указатель файла.

После окончания работы с файлом, он должен быть закрыт. Делается это с помощью библиотечной функции fclose, при этом связь файла с указателем файла разрывается.

Пример 1. Запишем в файл myFile1 данные, а затем выполним чтение этих данных из файла:

int n1 = 123, n2 = 6789, n3, n4;

char m1[] = «Character_data», m2[50];

fprintf(fp, «%d %d %s», n1, n2, m1); //запись данных в файл из n1, n2 и массива m1

fclose(fp); //закрытие файла

fp = fopen(«myFile1», «r»); //открытие файла на чтение

fscanf(fp, «%d%d%s», &n3, &n4, m2); //чтение данных из файла в n3, n4 и массив m2

fclose(fp); //закрытие файла

puts(«—— Numbers and string: ——«);

printf(«%d %d %s», n3, n4, m2); //вывод данных на экран из n3, n4 и массива m2

puts(«»); //переход к новой строке

Все то же самое можно выполнить, открывая файл один раз и используя функцию rewind для перемещения указателя файла к началу файла:

fp = fopen(«myFile1», «w+»); //открытие файла на запись и чтение

fprintf(fp, «%d %d %s», n1, n2, m1); //запись данных в файл

rewind(fp); //переход к началу файла

fscanf(fp, «%d%d%s», &n3, &n4, m2); //чтение данных из файла

fclose(fp); //закрытие файла

printf(«%d %d %s\n», n3, n4, m2); //вывод данных на экран

Пример 2. Запишем в файл, а затем прочитаем из него структуру данных:

int N_zachetki, god_rogdenia;

fp = fopen(«myFile2», «w+»); //открытие файла на запись и чтение

fprintf(fp, «%s %d %d», stu.familia, stu.N_zachetki, stu.god_rogdenia); //запись данных

rewind(fp); //переход к началу файла

fscanf(fp, «%s%d%d», m2, &n3, &n4); //чтение данных из файла

fclose(fp); //закрытие файла

printf(«%s %d %d\n», m2, n3, n4); //вывод данных на экран

Пример 3. Запишем в файл и прочитаем из него массив данных:

fp = fopen(«myFile3», «w+»); //открытие файла на запись и чтение

Дата добавления: 2020-04-03 ; просмотров: 499 | Нарушение авторских прав

Файл: Форматированный вывод текста в файл

Добавлено через 3 минуты
нужно чтоб выводило результаты в файлы, в виде например reactions:
1. re(1) re(2)
2. re(3) re(4)

и также с остальными..

Добавлено через 12 минут
на экран выводит, в файл не получается

12.06.2020, 22:09

Форматированный вывод в файл
Подскажите пожалуйста как сделать форматированный вывод в файл. нужно просто оформить в виде.

Форматированный ввод/вывод в файл
подскажите как читать из файла или писать в файл например int ( не используя при этом fprintf &.

Вывод текста в файл
У меня есть двусвязный список Library, в нем записаны данные про книги.. мне нужно, что бы.

Вывод текста в файл
можно ли в c++ форматируемо записывать текст в файл? То есть некоторые слова выделять в файле.

Технология программирования на Си: представление матриц, работа с файлами и с текстами

Работа с файлами

Стандартная библиотека Си содержит набор функций для работы с файлами. Эти функции описаны в стандарте ANSI . Отметим, что файловый ввод-вывод не является частью языка Си , и ANSI -функции — не единственное средство ввода-вывода. Так, в операционной системе Unix более популярен другой набор функций ввода-вывода, который можно использовать не только для работы с файлами, но и для обмена по сети. В C++ часто используются библиотеки классов для ввода-вывода. Тем не менее, функции ANSI -библиотеки поддерживаются всеми Си -компиляторами, и потому программы, применяющие их, легко переносятся с одной платформы на другую. Прототипы функций ввода-вывода и используемые для этого типы данных описаны в стандартном заголовочном файле «stdio.h.

Открытие файла: функция fopen

Для доступа к файлу применяется тип данных FILE . Это структурный тип, имя которого задано с помощью оператора typedef в стандартном заголовочном файле «stdio.h». Программисту не нужно знать, как устроена структура типа файл: ее устройство может быть системно зависимым, поэтому в целях переносимости программ обращаться явно к полям струтуры FILE запрещено. Тип данных «указатель на структуру FILE используется в программах как черный ящик: функция открытия файла возвращает этот указатель в случае успеха, и в дальнейшем все файловые функции применяют его для доступа к файлу.

Прототип функции открытия файла выглядит следующим образом:

Здесь path — путь к файлу (например, имя файла или абсолютный путь к файлу), mode — режим открытия файла. Строка mode может содержать несколько букв. Буква » r » (от слова read) означает, что файл открывается для чтения (файл должен существовать). Буква » w » (от слова write) означает запись в файл, при этом старое содержимое файла теряется, а в случае отсутствия файла он создается. Буква » a » (от слова append) означает запись в конец существующего файла или создание нового файла, если файл не существует.

В некоторых операционных системах имеются различия в работе с текстовыми и бинарными файлами (к таким системам относятся MS DOS и MS Windows; в системе Unix различий между текстовыми и бинарными файлами нет). В таких системах при открытии бинарного файла к строке mode следует добавлять букву » b » (от слова binary), а при открытии текстового файла — букву » t » (от слова text). Кроме того, при открытии можно разрешить выполнять как операции чтения, так и записи; для этого используется символ + (плюс). Порядок букв в строке mode следующий: сначала идет одна из букв » r «, » w «, » a «, затем в произвольном порядке могут идти символы » b «, » t «, » + «. Буквы » b » и » t » можно использовать, даже если в операционной системе нет различий между бинарными и текстовыми файлами, в этом случае они просто игнорируются.

Значения символов в строке mode сведены в следующую таблицу:

r Открыть существующий файл на чтение
w Открыть файл на запись. Старое содержимое файла теряется, в случае отсутствия файла он создаётся.
a Открыть файл на запись. Если файл существует, то запись производится в его конец.
t Открыть текстовый файл.
b Открыть бинарный файл.
+ Разрешить и чтение, и запись.

Несколько примеров открытия файлов:

Обратите внимание, что во втором случае мы используем обычную косую черту / для разделения директорий, хотя в системах MS DOS и MS Windows для этого принято использовать обратную косую черту \ . Дело в том, что в операционной системе Unix и в языке Си, который является для нее родным, символ \ используется в качестве экранирующего символа, т.е. для защиты следующего за ним символа от интерпретации как специального. Поэтому во всех строковых константах Си обратную косую черту надо повторять дважды, как это и сделано в третьем примере. Впрочем, стандартная библиотека Си позволяет в именах файлов использовать нормальную косую черту вместо обратной; эта возможность была использована во втором примере.

Илон Маск рекомендует:  Iis изменение ограничений доступа (chaccess)

В случае удачи функция fopen открытия файла возвращает ненулевой указатель на структуру типа FILE , описывающую параметры открытого файла. Этот указатель надо затем использовать во всех файловых операциях. В случае неудачи (например, при попытке открыть на чтение несуществующий файл) возвращается нулевой указатель. При этом глобальная системная переменная errno, описанная в стандартном заголовочном файле «errno.h, содержит численный код ошибки. В случае неудачи при открытии файла этот код можно распечатать, чтобы получить дополнительную информацию:

Константа NULL

В приведенном выше примере при открытии файла функция fopen в случае ошибки возвращает нулевой указатель на структуру FILE . Чтобы проверить, произошла ли ошибка, следует сравнить возвращенное значение с нулевым указателем. Для наглядности стандартный заголовочный файл «stdio.h» определяет символическую константу NULL как нулевой указатель на тип void :

Сделано это вроде бы с благой целью: чтобы отличить число ноль от нулевого указателя. При этом язык Си, в котором контроль ошибок осуществляется недостаточно строго, позволяет сравнивать указатель общего типа void * с любым другим указателем. Между тем,в Си вместо константы NULL всегда можно использовать просто 0 , и вряд ли от этого программа становится менее понятной. Более строгий язык C++ запрещает сравнение разных указателей, поэтому в случае C++ стандартный заголовочный файл определяет константу NULL как обычный ноль:

Автор языка C++ Б. Страуструп советует использовать обычный ноль 0 вместо символического обозначения NULL . Тем не менее, по традиции большинство программистов любят константу NULL .

Константа NULL не является частью языка Си или C++, и без подключения одного из стандартных заголовочных файлов, в котором она определяется, использовать ее нельзя. (По этой причине авторы языка Java добавили в язык ключевое слово null , записываемое строчными буквами.) Так что в случае Си или C++ безопаснее следовать совету Б. Страуструпа и использовать обычный ноль 0 вместо символической константы NULL .

Диагностика ошибок: функция perror

Использовать переменную errno для печати кода ошибки не очень удобно, поскольку необходимо иметь под рукой таблицу возможных кодов ошибок и их значений. В стандартной библиотеке Си существует более удобная функция perror , которая печатает системное сообщение о последней ошибке вместо ее кода. Печать производится на английском языке, но есть возможность добавить к системному сообщению любой текст, который указывается в качестве единственного аргумента функции perror . Например, предыдущий фрагмент переписывается следующим образом:

Функция perror печатает сначала пользовательское сообщение об ошибке, затем после двоеточия системное сообщение. Например, при выполнении приведенного фрагмента в случае ошибки из-за отсутствия файла будет напечатано

Функции бинарного чтения и записи fread и fwrite

После того как файл открыт, можно читать информацию из файла или записывать информацию в файл. Рассмотрим сначала функции бинарного чтения и записи fread и fwrite . Они называются бинарными потому, что не выполняют никакого преобразования информации при вводе или выводе (с одним небольшим исключением при работе с текстовыми файлами, которое будет рассмотрено ниже): информация хранится в файле как последовательность байтов ровно в том виде, в котором она хранится в памяти компьютера.

Функция чтения fread имеет следующий прототип:

Здесь size_t определен как беззнаковый целый тип в системных заголовочных файлах. Функция пытается прочесть numElems элементов из файла, который задается указателем f на структуру FILE , размер каждого элемента равен elemSize . Функция возвращает реальное число прочитанных элементов, которое может быть меньше, чем numElems , в случае конца файла или ошибки чтения. Указатель f должен быть возвращен функцией fopen в результате успешного открытия файла. Пример использования функции fread :

В этом примере файл » tmp.dat » открывается на чтение как бинарный, из него читается 100 вещественных чисел размером 8 байт каждое. Функция fread возвращает реальное количество прочитанных чисел, которое меньше или равно, чем 100.

Функция fread читает информацию в виде потока байтов и в неизменном виде помещает ее в память. Следует различать текстовое представление чисел и их бинарное представление! В приведенном выше примере числа в файле должны быть записаны в бинарном виде, а не в виде текста. Для текстового ввода чисел надо использовать функции ввода по формату, которые будут рассмотрены ниже.

Внимание! Открытие файла как текстового с помощью функции fopen , например,

вовсе не означает, что числа при вводе с помощью функции fopen будут преобразовываться из текстовой формы в бинарную! Из этого следует только то, что в операционных системах, в которых строки текстовых файлов разделяются парами символами » \r\n » (они имеют названия CR и LF — возврат каретки и продергивание бумаги, Carriage Return и Line Feed ), при вводе такие пары символов заменяются на один символ » \n » (продергивание бумаги). Обратно, при выводе символ » \n » заменяется на пару » \r\n «. Такими операционными системами являются MS DOS и MS Windows. В системе Unix строки разделяются одним символом » \n » (отсюда проистекает обозначение » \n «, которое расшифровывается как new line). Таким образом, внутреннее представление текста всегда соответствует системе Unix, а внешнее — реально используемой операционной системе. Отметим также, что создатели операционной системы компьютеров Apple Macintosh выбрали, чтобы жизнь не казалась скучной, третий, отличный от двух предыдущих, вариант: текстовые строки разделяются одним символом » \r » возврат каретки!

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

Функция бинарной записи в файл fwrite аналогична функции чтения fread . Она имеет следующий прототип:

Функция возвращает число реально записанных элементов, которое может быть меньше, чем numElems , если при записи произошла ошибка — например, не хватило свободного пространства на диске. Пример использования функции fwrite :

Закрытие файла: функция fclose


По окончании работы с файлом его надо обязательно закрыть. Система обычно запрещает полный доступ к файлу до тех пор, пока он не закрыт. (Например, в нормальном режиме система запрещает одновременную запись в файл для двух разных программ.) Кроме того, информация реально записывается полностью в файл лишь в момент его закрытия. До этого она может содержаться в оперативной памяти (в так называемой файловой кеш -памяти), что при выполнении многочисленных операций записи и чтения значительно ускоряет работу программы.

Для закрытия файла используется функция fclose с прототипом

В случае успеха функция fclose возвращает ноль, при ошибке — отрицательное значение (точнее, константу конец файла EOF, определенную в системных заголовочных файлах как минус единица). При ошибке можно воспользоваться функцией perror , чтобы напечатать причину ошибки. Отметим, что ошибка при закрытии файла — явление очень редкое (чего не скажешь в отношении открытия файла), так что анализировать значение, возвращаемое функцией fclose , в общем-то, не обязательно. Пример использования функции fclose :

Пример: подсчет числа символов и строк в текстовом файле

В качестве содержательного примера использования рассмотренных выше функций файлового ввода приведем программу, которая подсчитывает число символов и строк в текстовом файле. Программа сначала вводит имя файла с клавиатуры. Для этого используется функция scanf ввода по формату из входного потока, для ввода строки применяется формат » %s . Затем файл открывается на чтение как бинарный (это означает, что при чтении не будет происходить никакого преобразования разделителей строк). Используя в цикле функцию чтения fread , мы считываем содержимое файла порциями по 512 байтов, каждый раз увеличивая суммарное число прочитанных символов. После чтения очередной порции сканируется массив прочитанных символов и подсчитывается число символов » \n » продергивания бумаги, которые записаны в концах строк текстовых файлов как в системе Unix, так и в MS DOS или MS Windows. В конце закрывается файл и печатается результат.

Пример выполнения программы: она применяется к собственному тексту, записанному в файле «wc.cpp.

Форматный ввод-вывод: функции fscanf и fprintf

В отличие от функции бинарного ввода fread , которая вводит байты из файла без всякого преобразования непосредственно в память компьютера, функция форматного ввода fscanf предназначена для ввода информации с преобразованием ее из текстового представления в бинарное. Пусть информация записана в текстовом файле в привычном для человека виде (т.е. так, что ее можно прочитать или ввести в файл, используя текстовый редактор). Функция fscanf читает информацию из текстового файла и преобразует ее во внутреннее представление данных в памяти компьютера. Информация о количестве читаемых элементов, их типах и особенностях представления задается с помощью формата. В случае функции ввода формат — это строка, содержащая описания одного или нескольких вводимых элементов. Форматы, используемые функцией fscanf , аналогичны применяемым функцией scanf , они уже неоднократно рассматривались (см. раздел 3.5.4). Каждый элемент формата начинается с символа процента » % «. Наиболее часто используемые при вводе форматы приведены в таблице:

%d целое десятичное число типа int (d — от decimal)
%lf вещ. число типа double (lf — от long float)
%c один символ типа char
%s ввод строки. Из входного потока выделяется слово, ограниченное пробелами или символами перевода строки ‘\n’. Слово помещается в массив символов. Конец слова отмечается нулевым байтом.

Прототип функции fscanf выглядит следующим образом:

Многоточие здесь означает, что функция имеет переменное число аргументов, большее двух, и что количество и типы аргументов, начиная с третьего, произвольны. На самом деле, фактические аргументы, начиная с третьего, должны быть указателями на вводимые переменные. Несколько примеров использования функции fscanf :

Функция fscanf возвращает число успешно введенных элементов. Таким образом, возвращаемое значение всегда меньше или равно количеству процентов внутри форматной строки (которое равно числу фактических аргументов минус 2).

Функция fprintf используется для форматного вывода в файл. Данные при выводе преобразуются в их текстовое представление в соответствии с форматной строкой. Ее отличие от форматной строки, используемой в функции ввода fscanf , заключается в том, что она может содержать не только форматы для преобразования данных, но и обычные символы, которые записываются без преобразования в файл. Форматы, как и в случае функции fscanf , начинаются с символа процента » % «. Они аналогичны форматам, используемым функцией fscanf . Небольшое отличие заключается в том, что форматы функции fprintf позволяют также управлять представлением данных, например, указывать количество позиций, отводимых под запись числа, или количество цифр после десятичной точки при выводе вещественного числа. Некоторые типичные примеры форматов для вывода приведены в следующей таблице:

%d вывод целого десятичного числа
%10d вывод целого десятичного числа, для записи числа отводится 10 позиций, запись при необходимости дополняется пробелами слева
%lf вывод вещественного число типа double в форме с фиксированной десятичной точкой
%.3lf вывод вещественного число типа double с печатью трёх знаков после десятичной точки
%12.3lf вывод вещественного число типа double с тремя знаками после десятичной точки, под число отводится 12 позиций
%c вывод одного символа
%s конец строки, т.е. массива символов. Конец строки задается нулевым байтом

Прототип функции fprintf выглядит следующим образом:

int fprintf(FILE *f, const char *format, . );

Многоточие, как и в случае функции fscanf , означает, что функция имеет переменное число аргументов. Количество и типы аргументов, начиная с третьего, должны соответствовать форматной строке. В отличие от функции fscanf , фактические аргументы, начиная с третьего, представляют собой выводимые значения, а не указатели на переменные. Для примера рассмотрим небольшую программу, выводящую данные в файл «tmp.dat»:

В результате выполнения этой программы в файл «tmp.dat» будет записан следующий текст:

В последнем примере форматная строка содержит внутри себя двойные апострофы. Это специальные символы, выполняющие роль ограничителей строки, поэтому внутри строки их надо экранировать (т.е. защищать от интерпретации как специальных символов) с помощью обратной косой черты \ , которая, напомним, в системе Unix и в языке Си выполняет роль защитного символа. Отметим также, что мы воспользовались стандартной функцией sqrt , вычисляющей квадратный корень числа, и стандартной функцией strlen , вычисляющей длину строки.

Понятие потока ввода или вывода

В операционной системе Unix и в других системах, использующих идеи системы Unix (например, MS DOS и MS Windows), применяется понятие потока ввода или вывода. Поток представляет собой последовательность байтов. Различают потоки ввода и вывода. Программа может читать данные из потока ввода и выводить данные в поток вывода. Программы можно запускать в конвейере, когда поток вывода первой программы является потоком ввода второй программы и т.д. Для запуска двух программ в конвейере используется символ вертикальной черты | между именами программ в командной строке. Например, командная строка

означает, что поток вывода программы ab направляется на вход программе cd , а поток вывода программы cd — на вход программе ef . По умолчанию, потоком ввода для программы является клавиатура, поток вывода назначен на терминал (или, как говорят программисты, на консоль). Потоки можно перенаправлять в файл или из файла, используя символы больше > и меньше , которые можно представлять как воронки. Например, командная строка

перенаправляет выходной поток программы abcd в файл «tmp.res», т.е. данные будут выводиться в файл вместо печати на экране терминала. Соответственно, командная строка

заставляет программу abcd читать исходные данные из файла «tmp.dat» вместо ввода с клавиатуры. Командная строка

перенаправляет как входной, так и выходной потоки: входной назначается на файл «tmp.dat», выходной — на файл «tmp.res».

В Си работа с потоком не отличается от работы с файлом. Доступ к потоку осуществляется с помощью переменной типа FILE * . В момент начала работы Си-программы открыты три потока:

  • stdin — стандартный входной поток. По умолчанию он назначен на клавиатуру;
  • stdout — стандартный выходной поток. По умолчанию он назначен на экран терминала;
  • stderr — выходной поток для печати информации об ошибках. Он также назначен по умолчанию на экран терминала.

Переменные stdin , stdout , stderr являются глобальными, они описаны в стандартном заголовочном файле «stdio.h. Операции файлового ввода-вывода могут использовать эти потоки, например, строка

вводит значение целочисленной переменной n из входного потока. Строка

выводит значение переменой n в выходной поток. Строка

выводит указанный текст в поток stderr , используемый обычно для печати сообщений об ошибках. Функция perror также выводит сообщения об ошибках в поток stderr .

По умолчанию, стандартный выходной поток и выходной поток для печати ошибок назначены на экран терминала. Однако операция перенаправления вывода в файл > действует только на стандартный выходной поток. Например, в результате выполнения командной строки

обычный вывод программы abcd будет записываться в файл «tmp.res», а сообщения об ошибках по-прежнему будут печататься на экране терминала. Для того чтобы перенаправить в файл «tmp.log» стандартный поток печати ошибок, следует использовать командную строку

(между двойкой и символом > не должно быть пробелов!). Двойка здесь означает номер перенаправляемого потока. Стандартный входной поток имеет номер 0, стандартный выходной поток — номер 1, стандартный поток печати ошибок — номер 2. Данная команда перенаправляет только поток stderr , поток stdout по-прежнему будет выводиться на терминал. Можно перенаправить потоки в разные файлы:

Таким образом, существование двух разных потоков вывода позволяет при необходимости отделить мух от котлет, т.е. направить нормальный вывод и вывод информации об ошибках в разные файлы.

Функции scanf и printf ввода и вывода в стандартные потоки

Поскольку ввод из стандартного входного потока, по умолчанию назначенного на клавиатуру, и вывод в стандартный выходной поток, по умолчанию назначенный на экран терминала, используются особенно часто, библиотека функций ввода-вывода Си предоставляет для работы с этими потоками функции scanf и printf . Они отличаются от функций fscanf и fprintf только тем, что у них отсутствует первый аргумент, означающий поток ввода или вывода. Строка

Описание функций языка Си

All | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

printf – вывод форматированной строки в стандартный поток вывода.

#include
int printf (const char *format, . );

format – указатель на строку c описанием формата.

При успешном завершении вывода возвращается количество выведенных символов.
При шибке возвращается отрицательное число.

Функция printf выводит в стандартный поток вывода строку отформатированную в соответствии с правилами, указанными в строке, на которую указывает аргумент format.

Правила задаются набором трех типов директив:
1. Обычные символы (кроме ‘%’ и ‘\’), которые выводятся без изменения;
2. Спецификаторы формата;
3. Специальные сиволы.

Каждый спецификатор формата начинается с символа ‘%’ и имеет следующий формат:

Спецификатор формата может иметь 0 или более [флагов], которые могут принемать значенияуказанные в таблице 1.

Таблица 1.

Флаг Назначение флага
— (дефис) Результат преобразования выравнивается по левому краю (по умолчанию — по правому краю)
+ Перед положительными числами выводится знак ‘+’, а перед отрицательыыми — знак ‘-‘ (по умолчанию выводится только знак ‘-‘ перед отрицательыми числами)
‘ ‘ (пробел) Если не указан модификатор ‘+’, то перед положительными числами, на месте знака числа, будет выводиться пробел.
# Использовать альтернативную форму представления выводимого числа. При выводе чисел в шестнадцатеричном формате (преобразователь ‘х’ или ‘Х’) перед числом будет указываться 0х или 0Х соответственно. При выводе чисел в восьмеричном формате (преобразователь ‘о’)перед числом будет указываться 0. При выводе чисел с плавующей точкой (преобразователи e, E, f, g и G) всегда будет содержаться десятичная точка (по умолчанию десятичная точка выводится только при ненулевой дробной части). При использовании преобразователей g и G хвостовые нули не будут удаляться (по умолчанию удаляются).
Если не указан флаг ‘-‘, то слева от выводимого числа будут выведены символы ‘0’ для подгона числа к указанной ширене. Если для преобразователей d, i, o, x или X указана точность, то флаг 0 игнорируется.
Илон Маск рекомендует:  Работа с mysql деревья

Спецификатор [флаги] можно не указывать.

Спецификатор [ширина] задаёт минимальный размер выводимого числа в символах. Если количество символов в выводимом числе меньше указанной минимальной ширины, то недостоющее количество символов заполняется нулями или пробелами слева или справа в зависимости от указанных флагов. Ширина указывается либо целым числом, либо символом * с последующим указанием имени переменной типа int, содержащей значение ширины, перед аргументом к которому он относится. Если аргумент имеет отрицательное значение, то он эквивалентен соответствующему положительному значению с флагом «-«.

Спецификатор [ширина] можно не указывать.

Действия спецификатора [точность] зависит от типа выводимого числа:

— Для типов d, i, o, u, x, X определяет минимальное число выводимых цифр. Если количество выводимых цифр в числе меньше, чем указано в спецификаторе [точность], то выводимое число будет дополнено нулями слева. Например, если при выводе числа 126 указать точность 4, то на экран будет выведено число 0126

— Для типов a, A, e, E, f, F определяет количество выводимых цифр после запятой. Если в выводимом числе количество значимых цифр после запятой меньше указанной точности, то недостающие символы выводятся нулями справа от числа. Если больше, то лишние цифры не выводятся. Например, если при выводе числа 126.345 указать точность 2, будет выведено на экран число 126.34, а если указать точность 5, то на экран будет выведено число 126.34500.

— Для типов g и G определяет максимальное выводимое число цифр. Например, если при выводе числа 126.345 указать точность 4, будет выведено на экран число 126.3. Если при выводе числа 1242679.23 указать точность 3, будет выведено на экран число 1.24е+06.

Точность указывается в виде символа точка, за которым следует десятичное число или символ «*», с последующим указанием имени переменной типа int, содержащей значение точности, перед аргументом к которому он относится.

Спецификатор [точность] можно не указывать.

Спецификатор [модификаторы] определяет размер выводимых данных (char, short, long, longlong). Спецификаторы используются для вывода чисел типа: char, short int, long int, long long int, long double или для явного преобразования выводимых данных. Например, если имеется переменная типа int, а необходимо вывести ее как short int. Доступные модификаторы приведены в таблице 2.

Таблица 2.

Модификатор Назначение модификатора
h Для вывода числа типа short int или unsigned short int. Или для явного преобразования при выводе целочисленного числа к типу short int или unsigned short int. Используется совместно с типами преобразования:d, i, o, u, x и X, n.
hh Для вывода числа типа char или unsigned char. Или для явного преобразования при выводе целочисленного числа к типу char или unsigned char. Используется совместно с типами преобразования:d, i, o, u, x и X, n.
l Для вывода числа типа long int или unsigned long int. Или для явного преобразования при выводе целочисленного числа к типу long int или unsigned long int. Используется совместно с типами преобразования:d, i, o, u, x и X, n.
ll Для вывода числа типа long long int или unsigned long long int. Или для явного преобразования при выводе целочисленного числа к типу long long int или unsigned long long int. Используется совместно с типами преобразования:d, i, o, u, x и X, n.
L Для вывода числа типа long double. Или для явного преобразования при выводе числа c плавающей точкой к типу long double. Используется совместно с типами преобразования:e, E, f, g и G.

Спецификатор [тип преобразования] определяет как надо итерпритировать и выводить число, например как знаковое целочисленное в десятичном виде, или беззнаковое целочисленное в шестнадцатеричном, или как число с плавающей точкой и так далее. Перечень доступных преобразований и их описание указано в таблице 3.

Таблица 3.

Тип преобразования Назначение преобразования
d,i Вывод целого числа со знаком в десятичной систем счисления. По умолчанию выводится число размером sizeof( int ), с правым выравниванием, указанием знака только для отрицательных чисел.
u Вывод целого числа без знака в десятичной систем счисления. По умолчанию выводится число размером sizeof( int ), с правым выравниванием.
o Вывод целого числа без знака в восьмеричной систем счисления. По умолчанию выводится число размером sizeof( int ), с правым выравниванием.
x, X Вывод целого числа без знака в шестнадцетеричной систем счисления. Причем для преобразования x используются символы abcdef, а для X — символы ABCDEF. По умолчанию выводится число размером sizeof( int ), с правым выравниванием.
f, F Вывод числа с плавающей точкой в виде [-]dddd.ddd. По умолчанию выводится число с точностью 6, если число по модулю меньше единицы, то пред десятично точкой выводится ноль, знак указывается только для отрицательных чисел, с правым выравниванием. Размер по умолчанию sizeof( double ).
e, E Вывод числа с плавающей точкой в экспоненциальной форме записи, в виде [-]dddd.ddde±dd, причем для модификатора e используется символ e, а для модификатора E — символ E. По умолчанию выводится число с точностью 6, если число по модулю меньше еденицы, то пред десятично точкой выводится ноль, знак указывается только для отрицательных чисел, с правым выравниванием. После символа «e» (или «E») всегда выводится две цифры (они равны 0, если аргумент равен 0).
g, G Вывод числа с плавающей точкой в форме зависищей от величины цисла. Например число 345.26 будет выведено как 345.26, а число 1344527.434 как 1.34453e+06. По умолчанию выводится 6 значащих цифр числа с округлением, если число по модулю меньше еденицы, то пред десятично точкой выводится ноль, знак указывается только для отрицательных чисел, с правым выравниванием.
a, A Вывод числа с плавающей точкой в шестнадцатеричном фомрате, в экспоненциальной форме записи. Например число 137.434 будет выведено как 0x1.12de353f7ced9p+7. Экспонента обозначается символом p. Для модификатора a используется символ p, а для модификатора A — символ P.По умолчанию знак указывается только для отрицательных чисел, выравнивание — правое.
с Вывод символа, соответстветсвующего числу указанному в аргументе функции. По умолчанию число приводится к типу unsigned char.
s Вывод строки, на которую ссылается указатель в аргументе функции printf. Строка выводится пока не будет встречен символ конец строки (/0). По умолчанию строка должна обозначаться как char*. Если указан модификатор l, то строка интерпитируется как wchar_t*. Для функции wprintf строка по умолчанию обрабатывается как wchar_t*.
S Аналогичен преобразованию s с модификатором l (ls).
p Вывод указателя. Результат ввода зависит от архитектуры и используемого компилятрора. Например, на 16 битной платформе MS-DOS вывод будет иметь вид типа FFAB:1402, а на 32-битной платформе с плоской адресацией — 00FC0120.
n Запись по адресу, указанному в аргументе функции, количества выведенных символов функцией printf до встречи преобразователя %n. При обработке преобразователя %n никакого вывода символов не производится.

Для форматирования вывода в функции printf предусмотрен набор специальных симовлов. Перечень специальных символов приведен в таблице 4.

printf()

Вот прототип функции printf() :

Функция printf() возвращает число выведенных символов или отрицательное значение в случае ошибки.

Управляющая_строка [1] состоит из элементов двух видов. Первый из них — это символы, которые предстоит вывести на экран; второй — это спецификаторы преобразования [2] , которые определяют способ вывода стоящих за ними аргументов. Каждый такой спецификатор начинается со знака процента, за которым следует код формата. Аргументов должно быть ровно столько, сколько и спецификаторов, причем спецификаторы преобразования и аргументы должны попарно соответствовать друг другу в направлении слева направо. Например, в результате такого вызова printf()

В этом примере первому спецификатору преобразования ( %c ), соответствует символ ‘C’, а второму ( %s ), — строка «и к тому же очень сильно!».

В функции printf() , как видно из табл. 8.2, имеется широкий набор спецификаторов преобразования.

Таблица 8.2. Спецификаторы преобразования для функции printf()
Код Формат
%a Шестнадцатеричное в виде 0xh.hhhhp+d (только С99)
%A Шестнадцатеричное в виде 0Xh.hhhhP+d (только С99)
%c Символ
%d Десятичное целое со знаком
%i Десятичное целое со знаком
%e Экспоненциальное представление (‘е’ на нижнем регистре)
%E Экспоненциальное представление (‘Е’ на верхнем регистре)
%f Десятичное с плавающей точкой
%g В зависимости от того, какой вывод будет короче, используется %е или %f
%G В зависимости от того, какой вывод будет короче, используется %Е или %F
%o Восьмеричное без знака
%s Строка символов
%u Десятичное целое без знака
%x Шестнадцатеричное без знака (буквы на нижнем регистре)
%X Шестнадцатеричное без знака (буквы на верхнем регистре)
%p Выводит указатель
%n Аргумент, соответствующий этому спецификатору, должен быть указателем на целочисленную переменную. Спецификатор позволяет сохранить в этой переменной количество записанных символов (записанных до того места, в котором находится код %n )
%% Выводит знак %

Вывод символов

Для вывода отдельного символа используйте %с . В результате соответствующий аргумент будет выведен на экран без изменения.

Для вывода строки используйте %s .

Вывод чисел

Числа в десятичном формате со знаком отображаются с помощью спецификатора преобразования %d или %i . Эти спецификаторы преобразования эквивалентны; оба поддерживаются в силу сложившихся привычек программистов, например, из-за желания поддерживать те же спецификаторы, которые применяются в функции scanf() .

Для вывода целого значения без знака используйте %u .

Спецификатор преобразования %f дает возможность выводить числа в формате с плавающей точкой. Соответствующий аргумент должен иметь тип double .

Спецификаторы преобразования %e и %E в функции printf() позволяют отображать аргумент типа double в экспоненциальном формате. В общем виде числа в таком формате выглядят следующим образом:

Чтобы отобразить букву E в верхнем регистре, используйте спецификатор преобразования %E ; в противном случае используйте спецификатор преобразования %e .

Спецификатор преобразования %g или %G указывает, что функции printf() необходимо выбрать один из спецификаторов: %f или %e . В результате printf() выберет тот спецификатор преобразования, который позволяет сделать самый короткий вывод. Если нужно, чтобы при выборе экспоненциального формата буква E отображалась на верхнем регистре, используйте спецификатор преобразования %G ; в противном случае используйте спецификатор преобразования %g .

Применение спецификатора преобразования %g показано в следующей программе:

В результате выполнения получится следующее:

Целые числа без знака можно выводить в восьмеричном или шестнадцатеричном формате, используя спецификатор преобразования %o или %x . Так как в шестнадцатеричной системе для представления чисел от 10 до 15 используются буквы от А до F, то эти буквы можно выводить на верхнем или на нижнем регистре. Как показано ниже, в первом случае используется спецификатор преобразования %X , а во втором — спецификатор преобразования %x :

Вот что вывела эта программа:

Отображение адреса

Для отображения адреса используйте спецификатор преобразования %p . Этот спецификатор преобразования дает printf() указание отобразить машинный адрес в формате, совместимом с адресацией, которая используется компьютером. Следующая программа отображает адрес переменной sample :

Спецификатор преобразования %n

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

Программа отображает строку Это проверка , после которой появляется число 3 . Спецификатор преобразования %n в основном используется в программе для выполнения динамического форматирования.

Модификаторы формата

Во многих спецификаторах преобразования можно указать модификаторы [3] , которые слегка меняют их значение. Например, можно указывать минимальную ширину поля, количество десятичных разрядов и выравнивание по левому краю. Модификатор формата помещают между знаком процента и кодом формата. Об этих модификаторах сейчас и пойдет речь.

Модификаторы минимальной ширины поля

Целое число, расположенное между знаком % и кодом формата, играет роль модификатора минимальной ширины поля . Если указан модификатор минимальной ширины поля, то чтобы ширина поля вывода была не меньше указанной минимальной длины, при необходимости вывод будет дополнен пробелами. Если же выводятся строки или числа, которые длиннее указанного минимума, то они все равно будут отображаться полностью. По умолчанию для дополнения используются пробелы. А если для этого надо использовать нули, то перед модификатором ширины поля следует поместить 0. Например, %05d означает, что любое число, количество цифр которого меньше пяти, будет дополнено таким количеством нулей, чтобы число состояло из пяти цифр. В следующей программе показано, как применяется модификатор минимальной ширины поля:

Вот что выводится при выполнении этой программы:

Модификатор минимальной ширины поля чаще всего используется при создании таблиц, в которых столбцы должны быть выровнены по вертикали. Например, следующая программа выводит таблицу квадратов и кубов чисел от 1 до 19: А вот пример полученного с ее помошью вывода:

Модификаторы точности

Модификатор точности следует за модификатором минимальной ширины поля (если таковой имеется). Он состоит из точки и расположенного за ней целого числа. Значение этого модификатора зависит от типа данных, к которым его применяют.

Когда модификатор точности применяется к данным с плавающей точкой, для преобразования которых используются спецификаторы преобразования %f , %e или %E , то он определяет количество выводимых десятичных разрядов. Например, %10.4f означает, что ширина поля вывода будет не менее 10 символов, причем для десятичных разрядов будет отведено четыре позиции.

Если модификатор точности применяется к %g или %G , то он определяет количество значащих цифр.

Примененный к строкам, модификатор точности определяет максимальную длину поля. Например, %5.7s означает, что длина выводимой строки будет составлять минимум пять и максимум семь символов. Если строка окажется длиннее, чем максимальная длина поля, то конечные символы выводиться не будут.

Если модификатор точности применяется к целым типам, то он определяет минимальное количество цифр, которые будут выведены для каждого из чисел. Чтобы получилось требуемое количество цифр, добавляется некоторое количество ведущих нулей.

В следующей программе показано, как можно использовать модификатор точности:

Вот что выводится при выполнении этой программы:

Выравнивание вывода

По умолчанию весь вывод выравнивается по правому краю. То есть если ширина поля больше ширины выводимых данных, то эти данные располагаются по правому краю поля. Вывод по левому краю можно назначить принудительно, поместив знак минус прямо за % . Например, %-l0.2f означает, что число с плавающей точкой и с двумя десятичными разрядами будет выровнено по левому краю 10-символьного поля.

В следующей программе показано, как применяется выравнивание по левому краю:

И вот что получилось:

Обработка данных других типов

Некоторые модификаторы в вызове функции printf() позволяют отображать целые числа типа short и long . Такие модификаторы можно использовать для следующих спецификаторов типа: d , i , o , u и x . Модификатор l (эль) в вызове функции printf() указывает, что за ним следуют данные типа long . Например, %ld означает, что надо выводить данные типа long int . После модификатора h функция printf() выведет целое значение в виде short . Например, %hu означает, что выводимые данные имеют тип short unsigned int .

Модификаторы l и h можно также применить к спецификатору n . Это делается с той целью, чтобы показать — соответствующий аргумент является указателем соответственно на длинное ( long ) или короткое ( short ) целое.

Если компилятор поддерживает обработку символов в расширенном 16-битном алфавите, добавленную Поправкой 1 от 1995 года (1995 Amendment 1), то для указания символа в расширенном 16-битном алфавите вы можете применять модификатор 1 для спецификатора преобразования c . Кроме того, для указания строки из символов в расширенном 16-битном алфавите можно применять модификатор 1 для спецификатора преобразования s .

Модификатор L может находиться перед спецификаторами преобразования с плавающей точкой e , f и g , и указывать этим, что преобразуется значение long double .

В Стандарте С99 вводится два новых модификатора формата: hh и ll . Модификатор hh можно применять для спецификаторов преобразования d , i , o , u , x или n . Он показывает, что соответствующий аргумент является значением signed или unsigned char или, в случае n , указателем на переменную signed char . Модификатор ll также можно применять для спецификаторов преобразования d , i , o , u , x или n . Он показывает, что соответствующий аргумент является значением signed или unsigned long long int или, в случае n , указателем на long long int . В С99 также разрешается применять l для спецификаторов преобразования с плавающей точкой a , е , f и g ; впрочем, это не дает никакого результата.

На заметку В составе С99 имеются некоторые дополнительные модификаторы типа для функции printf() ; о них рассказывается в части II.

Модификатор * и #

Для некоторых из своих спецификаторов преобразования функция printf() поддерживает два дополнительных модификатора: * и # .

Непосредственное расположение # перед спецификаторами преобразования g , G , f , Е или e означает, что при выводе обязательно появится десятичная точка — даже если десятичных цифр нет. Если вы поставите # непосредственно перед x или X , то шестнадцатеричное число будет выведено с префиксом 0x . Если # будет непосредственно предшествовать спецификатору преобразования o , число будет выведено с ведущим нулем. К любым другим спецификаторам преобразования модификатор # применять нельзя. (В С99 модификатор # можно применять по отношению к преобразованию %а ; это значит, что обязательно будет выведена десятичная точка.)

Модификаторы минимальной ширины поля и точности можно передавать функции printf() не как константы, а как аргументы. Для этого в качестве заполнителя используйте звездочку ( * ). При сканировании строки формата функция printf() будет каждой звездочке * из этой строки ставить в соответствие очередной аргумент, причем в том порядке, в каком расположены аргументы. Например, при выполнении оператора, показанного на рис. 8.1, минимальная ширина поля будет равна 10 символам, точность — 4, а отображаться будет число 123.3 .

В следующей программе показано применение обоих модификаторов # и * :

Рис. 8.1. Обратите внимание на то, каким образом звездочке (*) ставится в соответствие определенное значение

[1] Часто называется просто форматной строкой , форматным стрингом или форматом .

[2] Называются также спецификациями формата .

[3] Называются также спецификаторами .

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL