Форматированный ввод и вывод в строки. Функции sscanf и sprintf

Последнее обновление: 06.02.2023

Функция sscanf считывает данные из строки (массива символов) в переменные. Функция имеет следующий синтаксис

int sscanf (const char * buffer, const char * format, …);

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

Считаем данные из строки

#include <stdio.h>

int main(void)
{
	char buff[50] = "F 69 123.45";
 	char c;
 	int n;
 	double d;
 	sscanf(buff, "%c %d %lf", &c, &n, &d);
 	printf("Values: %c, %d, %lf\n", c, n, d);
	return 0;
}

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

"F 69 123.45"

Разделителем между значениями является пробел, либо последовательность пробелов, табуляция и перевод строки.

Эту строку передаем в функцию sscanf первым аргументом и считываем ее значения в переменные c, n, d:

А второй аргумент - формат считывания определяет, как данные из строки будут сопоставляться с переменными:

"%c %d %lf"

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

Второй спецификатор - %d обеспечивает считывание целого числа в переменную n.

И третий спецификатор %lf считывает данные в переменную типа double - d

То есть в итоге консольный вывод был бы следующим:

Values: F, 69, 123.450000

Обратите внимание, что формат считывания соответствует строке, из которой считываются данные. Если бы в строке данные были бы разделены запятыми, то спецификаторы в формате считывания также были бы разделены запятыми:

#include <stdio.h>

int main(void)
{
	char buff[50] = "F, 69, 123.45";
 	char c;
 	int n;
 	double d;
 	sscanf(buff, "%c, %d, %lf", &c, &n, &d);
 	printf("Values: %c, %d, %.2lf\n", c, n, d);
	return 0;
}

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

#include <stdio.h>

int main(void)
{
	char buff[50] = "Tom 23 505.99";
 	char name[10];
 	int age;
 	double salary;
 	sscanf(buff, "%s %d %lf", name, &age, &salary);
 	printf("Name: %s \tAge: %d \tSalary: %.2lf\n", name, age, salary);
	return 0;
}

Причем строка форматирования может быть более сложной. Например:

#include <stdio.h>

int main(void)
{
    char *buff = "Name is Tom and age is 38";
    char name[10];
    int age;

    sscanf(buff, "Name is %s and age is %d", name, &age);

    printf("Name: %s \tAge: %d\n", name, age);  // Name: Tom       Age: 38
    return 0;
}

В данном случае исходная строка представляет текст "Name is Tom and age is 38". И на эту строку накладывается строка форматирования "Name is %s and age is %d". Соответственно здесь спецификатор %s будет представлять строку "Tom", а спецификатор %d - число 38.

Считывание с консоли

Комбинируя это функцию с fgets(), можно считывать данные с консоли:

#include <stdio.h>

int main(void)
{
	char buff[50];
 	char name[10];
 	int age;
 	double salary;
    printf("Enter the data\n");
    if(!fgets(buff, 50, stdin))
    {
        printf("Fatal Error!\n");
        return 1;
    }
 	sscanf(buff, "%s %d %lf", name, &age, &salary);
 	printf("Name: %s \tAge: %d \tSalary: %.2lf\n", name, age, salary);
	return 0;
}

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

Enter the data
Tom 38 456.78
Name: Tom       Age: 38         Salary: 456.78

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

sprintf

Функция sprintf производит обратное действие - записывает данные в строку:

int sprintf(char *_Buffer, const char *_Format, ...)

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

Пример использования:

#include <stdio.h>

void main (void)
{
    int age = 38;
    char* name = "Tom";
    char text[50];  
    int charNumber = sprintf (text, "Name: %s  Age: %d\n", name, age);  
    printf (text);  // Name: Tom  Age: 38
    printf("text length: %d", charNumber);  // text length: 19
}

В данном случае в переменную text записывается строка "Name: %s Age: %d\n", в которую вместо спецификаторов подставляются значения переменных name и age.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850