Ввод-вывод (printf, scanf), использование библиотеки stdio.h

Ввод-вывод в Си

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

Ввод и вывод информации осуществляется через функции стандартной библиотеки. Прототипы рассматриваемых функций находятся в файле stdio.h. Эта библиотека содержит функции

  • printf() — для вывода информации
  • scanf() — для ввода информации.

Вывод информации

Функция printf() предназначена для форматированного вывода. Она переводит данные в символьное представление и выводит полученные изображения символов на экран. При этом у программиста имеется возможность форматировать данные, то есть влиять на их представление на экране.

Общая форма записи функции printf():

 
printf("СтрокаФорматов", объект1, объект2, …, объектn);

СтрокаФорматов состоит из следующих элементов:

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

Объекты могут отсутствовать.

Управляющие символы не выводятся на экран, а управляют расположением выводимых символов. Отличительной чертой управляющего символа является наличие обратного слэша '\' перед ним.

Основные управляющие символы:

  • '\n' — перевод строки;
  • '\t' — горизонтальная табуляция;
  • '\v' — вертикальная табуляция;
  • '\b' — возврат на символ;
  • '\r' — возврат на начало строки;
  • '\a' — звуковой сигнал.
Форматы нужны для того, чтобы указывать вид, в котором информация будет выведена на экран. Отличительной чертой формата является наличие символа процент ‘%’ перед ним:
  • %d — целое число типа int со знаком в десятичной системе счисления;
  • %u — целое число типа unsigned int;
  • %x — целое число типа int со знаком в шестнадцатеричной системе счисления;
  • %o — целое число типа int со знаком в восьмеричной системе счисления;
  • %hd — целое число типа short со знаком в десятичной системе счисления;
  • %hu — целое число типа unsigned short;
  • %hx — целое число типа short со знаком в шестнадцатеричной системе счисления;
  • %ld — целое число типа long int со знаком в десятичной системе счисления;
  • %lu — целое число типа unsigned long int;
  • %lx — целое число типа long int со знаком в шестнадцатеричной системе счисления;
  • %f — вещественный формат (числа с плавающей точкой типа float);
  • %lf — вещественный формат двойной точности (числа с плавающей точкой типа double);
  • %e — вещественный формат в экспоненциальной форме (числа с плавающей точкой типа float в экспоненциальной форме);
  • %c — символьный формат;
  • %s — строковый формат;
  • %p — указатель, вывод адреса переменной.

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

Пример на Си

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main()
{
int a = 5;
float x = 2.78;
printf("a=%d\n", a);
printf("x=%f\n", x);
getchar();
return 0;
}

Результат работы программы

Вывод на Си

Тот же самый код может быть представлен с использованием одного вызова printf:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main()
{
  int a = 5;
  float x = 2.78;
  printf("a=%d\nx=%f\n", a, x);
  getchar();
  return 0;
}

Табличный вывод

При указании формата можно явным образом указать общее количество знакомест и количество знакомест, занимаемых дробной частью:

1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
  float x = 1.2345;
  printf("x=%10.5f\n", x);
  getchar();
  return 0;
}

Результат выполнения
Форматированный вывод в Си

В приведенном примере

  • 10 — общее количество знакомест, отводимое под значение переменной;
  • 5 — количество позиций после разделителя целой и дробной части (после десятичной точки).

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

Ввод информации

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

 
scanf ("CтрокаФорматов", адрес1, адрес2,...);

Строка форматов аналогична функции printf(). Для формирования адреса переменной используется символ амперсанд '&': адрес = &объект

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

Пример на Си

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf в Visual Studio
#include <stdio.h>
#include <stdlib.h> // для перехода на русский язык
int main()
{
  float y;
  system("chcp 1251"); // переходим в консоли на русский язык
  system("cls");       // очищаем окно консоли
  printf("Введите y: "); // выводим сообщение
  scanf("%f", &y);     // вводим значения переменной y
  printf("Значение переменной y=%f", y); // выводим значение переменной y
  getchar(); getchar();
  return 0;
}

Результат работы программы:

Функция scanf()

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

 
#define _CRT_SECURE_NO_WARNINGS 

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

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main()
{
  int a;
  printf("a = ");
  scanf_s("%d", &a);
  printf("a = %d",a);
  getchar(); getchar();
  return 0;
}

26 комментариев к “Ввод-вывод в Си”

  1. Здравствуйте у меня проблема

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include<stdio.h>
    void  sorting(int *tmp, int ptm)
    {
     int min, curr;
      for ( int i = 0; i < ptm; i++)
      {
        min = i;
        for (int t = i + 1; t < ptm; t++)
        {

          if (tmp[t] < tmp[min])
              min = t;
        }
        curr = tmp[i];
        tmp[i] = tmp[min];
        tmp[min] = curr;
      }
    }
    int main()
    {
      int a[10];

      for (int i = 0; i < 10; i++)
      {
        printf("a%d= ", i);
        scanf("%x", &a[i]);
      }
      sorting(a,10);
      for (int i = 0; i<10; i++)
        printf("%d ", a[i]);
      return 0;
    }

    1. Елена Вставская

      i должно меняться до ptm-1. Иначе t=i+1 окажется за границами массива

  2. Кирилл

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h>
    #include <math.h>
    void main()
    {
      int c, f;
      float a, y;
      c = 1;
      f = 0;
      printf("Enter a: ");
      scanf_s("%f", &a);
      for (float x = -1.7; x <= 3.3; x += 0.5)
        if ((3.0 * a) + sin(x / 3) == 0)
          f = 1;
      if (f == 0)
      {
        printf("___________________________________________\n");
        printf("|Number|  x  |       a      |     y(x)    |\n");
        printf("|______|_____|______________|_____________|\n");
        for (float x = -1.7; x <= 3.3; x += 0.5)
        {
          y = (2.0 * x) / ((3.0 * a) + sin(x / 3));
          printf("|%4d  |%5.1f|%14f|%13f|\n", c, x, a, y);
          printf("|______|_____|______________|_____________|\n");
          c++;
        }
      }
      else
      {
        printf("___________________________________________________________________________________________\n");
        for (int i = 1; i <= 12; i++)
        {
          printf("|Error: division by 0 | Error: division by 0 | Error: division by 0 | Error: division by 0|\n");
          printf("|_____________________|______________________|______________________|_____________________|\n");
        }
      }
    1. Елена Вставская

      Число 123456.123456 (с такой точностью) не помещается в разрядную сетку типа float. Используйте double.

  3. Виктор

    Добрый день. Подскажите пожалуйста, как сделать так, чтобы при вводе числа, например 12345, вывод был равен сумме 1+2+3+4+5=15 и потом 1+5=6.
    Язык Си. Большое спасибо за ответ!

    1. Через остаток от деления можно
      т.е
      12345 %10 = 5
      5/(10/10)=5 последняя цифра
      (12345 — 5) % 100 = 40
      40 /(100/10) = 4
      (12340- 40)%1000 = 300
      300/(1000/10) = 3
      (12300 — 300) /10000 = 2000
      2000/(10000/10)=2
      Первая цифра немного по другому
      10000/10000 = 1

  4. Прошу подсказать как запретить ввод более одного символа. Чтобы на экране нельзя было ввести более одного символа например y или n. И далее ждать нажатия enter. Но с возможностью удалить и ввести другую букву пока не нажат enter. В интернете нашла такую программу но потеряла.

    1. Елена Вставская

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      #include <stdio.h>
      #include <ctype.h>
      #include <conio.h>
      int main() {
        int count = 0; // количество символов
        char ch;
        char resp;
        do {
          ch = _getch(); // считывание символа без показа в консоль
          if (((ch == 'y') || (ch == 'n') || (ch == 'Y') || (ch == 'N')) && (count == 0))
          {
            resp = toupper(ch); // сохранение ответа
            putchar(resp); // вывод ответа в консоль
            count++;
          }
          else
          {
            if (ch == 8) // Backspace
            {
              if (count > 0)
              {
                count = 0;
                putchar(ch);
              }
            }
          }
        } while (ch != 13); // пока не нажали Enter
        return 0;
      }
    2. Спасибо большое за программу. Работает. Единственно только при нажатии backspase введенная буква не стирается (не пропадает) с экрана. А заменяется другой буквой когда на клавиатуре нажимается другая кнопка.
      Немного подправила код если нажата клавиша backspase, добавила две строки. Теперь вроде работает так как я хотела.

      1
      2
      3
      4
      5
      6
      7
      if (count > 0)
              {
             count = 0;
             putchar(ch);  
          putchar(' ');
          putchar(ch);
              }
  5. Елена Вставская

    1
    fprintf(fp, "%s %d\n", str, counter);

    fp — указатель на файл, str — строка, counter — счётчик.
    Я правильно поняла Вас?

  6. Добрый день, подскажите: как сделать ввод в формате input.txt, а вывод в формате output.txt?

  7. Борис

    Добрый день!
    Скажите, пожалуйста, как вывести числа:
    Два числа, первое число типа float, выровненное по левому краю, второе — беззнаковое шестнадцатеричное целое, выровненное по правому.
    Первое число должно быть выведено в поле, которое занимает 25 позиций, второе — 6.
    Первое число должно быть выведено с точностью 10.
    Для второго числа в выводе 10…15 необходимо использовать прописные буквы.

    1. Борис

      Скажем, если числа a и b, соответственно:

      1
      printf("%-25.10f", a, "%10.15x", b);

      Верно?

  8. 1) с помощью sprintf(…) сформировать форматную строку с нужной точностью
    2) получившуюся строку передать как аргумент для printf(…)

    Например:

    1
    2
    3
    4
    char buf[256];
    int length = 8, precision = 5;
    sprintf(buf, "Value: %%%d.%df", length, precision); // Value: %8.5d
    printf(buf, 3.14159265358979); // напечатает Value: 3.14159
  9. Антонина

    Елена, здравствуйте! Можете пояснить для чего именно нужен макрос(?) _CRT_SECURE_NO_WARNINGS ? Если уже отвечали, дайте ссылку, пожалуйста. В гугле вменяемого объяснения не нашла. Используется ли он для каких-то других функций? Помимо scanf(). Спасибо заранее!

    1. Елена Вставская

      Visual Studio последних версий при компиляции выдает ошибки на использование некоторых незащищённых функций. Это функция scanf(), копирование строки strcpy(), функции работы с файлами и прочие. Если всё-таки необходимо использовать в программе эти функции, то этой строчкой можно заставить компилятор не воспринимать использование незащищённых функций за ошибку.

  10. Ирина

    Правильно ли я поняла, что для ввода 4-х значного целого числа можно использовать формат %4d , т.е  scanf("%4d", &y) ?

    1. Елена Вставская

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

    1. Елена Вставская

      \t — горизонтальная табуляция — отступ, чтобы при выводе значений в несколько столбиков они выводились друг под другом.
      \v — вертикальная табуляция — переводит курсор на следующую строку и начинает вывод не с начала строки, а с текущей позиции, но в некоторых случаях срабатывает некорректно.
      \a — звуковой сигнал, который слышен при «выводе на печать» этого символа.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх