Функция стандартного ввода scanf() — КиберПедия 

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

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Функция стандартного ввода scanf()

2018-01-04 107
Функция стандартного ввода scanf() 0.00 из 5.00 0 оценок
Заказать работу

 

Функция scanf () - функция форматированного ввода. С её помощью вы можете вводить данные со стандартного устройства ввода (клавиатуры). Вводимыми данными могут быть целые числа, числа с плавающей запятой, символы, строки и указатели.

Функция scanf () имеет следующий прототип в файле stdio.h:

int scanf(char *управляющая строка);

Функция возвращает число переменных, которым было присвоено значение.

Управляющая строка содержит три вида символов: спецификаторы формата, пробелы и другие символы. Спецификаторы формата начинаются с символа %.

Спецификаторы формата:

%c чтение символа
%d чтение десятичного целого
%i чтение десятичного целого
%e чтение числа типа float (плавающая запятая)
%h чтение short int
%o чтение восьмеричного числа
%s чтение строки
%x чтение шестнадцатеричного числа
%p чтение указателя
%n чтение указателя в увеличенном формате

 

При вводе строки с помощью функции scanf () (спецификатор формата %s), строка вводиться до первого пробела!! т.е. если вы вводите строку "Привет мир!" с использованием функции scanf ()

char str[80]; // массив на 80 символов
scanf("%s",str);

то после ввода результирующая строка, которая будет храниться в массиве str будет состоять из одного слова "Привет". ФУНКЦИЯ ВВОДИТ СТРОКУ ДО ПЕРВОГО ПРОБЕЛА! Если вы хотите вводить строки с пробелами, то используйте функцию

char *gets(char *buf);

С помощью функции gets () вы сможете вводить полноценные строки. Функция gets () читает символы с клавиатуры до появления символа новой строки (\n). Сам символ новой строки появляется, когда вы нажимаете клавишу enter. Функция возвращает указатель на buf. buf - буфер (память) для вводимой строки.

Пример программы, которая позволяет ввести целую строку с клавиатуры и вывести её на экран:

#include <stdio.h>

void main(void)
{
char buffer[100]; // массив (буфер) для вводимой строки

gets(buffer); // вводим строку и нажимаем enter
printf("%s",buffer); // вывод введённой строки на экран
}

Ещё одно важное замечание! Для ввода данных с помощью функции scanf (), ей в качестве параметров нужно передавать адреса переменных, а не сами переменные. Чтобы получить адрес переменной, нужно поставить перед именем переменной знак & (амперсанд). Знак & означает взятие адреса.

Что значит адрес? Попробую объяснить. В программе у нас есть переменная. Переменная хранит своё значение в памяти компьютера. Так вот адрес, который мы получаем с помощью & это адрес в памяти компьютера, где храниться значение переменной.

Давайте рассмотрим пример программы, который показывает нам как использовать &

#include <stdio.h>

void main(void)
{
int x;

printf("Введите переменную x:");
scanf("%d",&x);
printf("Переменная x=%d",x);
}

Теперь давайте вернёмся к управляющей строке функции scanf (). Ещё раз:

int scanf(char *управляющая строка);

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

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

Например:

scanf("%d%*c%d",&i,&j);

при вводе 50+20 присвоит переменной i значение 50, переменной j - значение 20, а символ + будет прочитан и проигнорирован.

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

Например:

scanf("%5s",str);

указывает необходимость прочитать из потока ввода первые 5 символов. При вводе 1234567890ABC массив str будет содержать только 12345, остальные символы будут проигнорированы. Разделители: пробел, символ табуляции и символ новой строки - при вводе символа воспринимаются, как и все другие символы.

Если в управляющей строке встречаются какие-либо другие символы, то они предназначаются для того, чтобы определить и пропустить соответствующий символ. Поток символов 10plus20 оператором

scanf("%dplus%d",&x,&y);

присвоит переменной x значение 10, переменной y - значение 20, а символы plus пропустит, так как они встретились в управляющей строке.

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

#include <stdio.h>

void main(void)
{
char str1[10], str2[10];
scanf("%[0123456789]%s", str1, str2);
printf("\n%s\n%s",str1,str2);
}
Введём набор символов:
12345abcdefg456

На экране программа выдаст:
12345
abcdefg456

При задании множества поиска можно также использовать символ " дефис " для задания промежутков, а также максимальную ширину поля ввода.

scanf("%10[A-Z1-5]", str1);

Можно также определить символы, которые не входят во множество поиска. Перед первым из этих символов ставиться знак ^. Множество символов различает строчные и прописные буквы.

Напомню, что при использовании функции scanf (), ей в качестве параметров нужно передавать адреса переменных. Выше был написан код:

char str[80]; // массив на 80 символов
scanf("%s",str);

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

Примеры программ.

 

Пример 1.
Эта программа выводит на экран запрос " Сколько вам лет?: " и ждёт ввода данных. Если, например, ввести число 20, то программа выведет строку " Вам 20 лет. ". При вызове функции scanf (), перед переменной age мы поставили знак &, так как функции scanf () нужны адреса переменных. Функция scanf () запишет введённое значение по указанному адресу. В нашем случае введённое значение 20 будет записано по адресу переменной age.

/* Пример 1 */

#include <stdio.h>

void main(void)
{
int age;

printf("\nСколько вам лет?:");
scanf("%d",&age);
printf("Вам %d лет.", age);
}

Пример 2.
Программа калькулятор. Этот калькулятор может только складывать числа. При вводе 100+34 программа выдаст результат: 100+34=134.

/* Пример 2 */

#include <stdio.h>

void main(void)
{
int x, y;

printf("\nКалькулятор:");
scanf("%d+%d", &x, &y);
printf("\n%d+%d=%d", x, y, x+y);
}

Пример 3.
Этот пример показывает, как установить ширину поля считывания. В нашем примере ширина поля равна пяти символам. Если вы введёте строку с большим количеством символов, то все символы после 5 -го будут отброшены. Обратите внимание на вызов функции scanf (). Знак & не стоит перед именем массива name, так как имя массива name является адресом первого элемента массива.

/* Пример 3 */

#include <stdio.h>

void main(void)
{
char name[5];

printf("\nВведите ваш логин (не более 5 символов):");
scanf("%5s", name);
printf("\nВы ввели %s", name);
}

Пример 4.
Последний пример в этой статье показывает, как можно использовать множество поиска. После запуска программы введите число от 2 до 5.

/* Пример 4 */

#include <stdio.h>

void main(void)
{
char bal;

printf("Ваша оценка 2,3,4,5:");
scanf("%[2345]", &bal);
printf("\nОценка %c", bal);
}


Приложение 3. Библиотека консольного ввода-вывода

 

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

 

/*

Это библиотека функций консольного ввода-вывода. Протестирована в среде MS Visual C++ 2010.

Для ее использования необходимо сохранить этот текст с файле с именем my_conio.h. Поместить

этот файл в каталог проекта и в тексте программы использовать директиву #include "my_conio.h"

*/

 

#pragma once

 

#include <windows.h> // Для CharToOemA

#include <conio.h> // Для getch()

#include <iostream>

 

using namespace std;

 

//

// Прототипы функций

//

 

char *Rus(char *sfrom, char *sto);

/*

Вывод текста, содержащего русские символы.

Использование:

char s[100];

cout << Rus("Это текст на русском языке!\n", s);

*/

char *Rus(char *s);

/*

Вывод текста, содержащего русские символы.

Использование:

char s[] = "И это текст на русском языке!\n";

cout << Rus(s);

 

*/

void out_Text(char *s);

/*

Вывод текста (и русского) без перехода на новую строку.

Использование:

out_Text("Это текст");

Ограничение: длина текста не более 255 символов

*/

void out_Text_ln(char *s);

/*

Вывод текста (и русского) с переходом на новую строку.

Использование:

out_Text_ln("Это текст");

Ограничение: длина текста не более 255 символов

*/

void Pause();

/*

Приостановка выполнения программы

*/

 

//

// Реализация функций

//

 

char *Rus(char *sfrom, char *sto)

{

CharToOemA(sfrom, sto);

return sto;

}

 

char *Rus(char *s)

{

CharToOemA(s, s);

return s;

}

 

void out_Text(char *s)

{

char S[256];

if (strlen(s) <= 255)

CharToOemA(s, S);

else

CharToOemA("Ошибка. Длина текста больше 255 символов", S);

cout << S;

}

 

void out_Text_ln(char *s)

{

out_Text(s);

cout << endl;

}

 

void Pause()

{

out_Text("Для продолжения нажмите любую клавишу...\n");

_getch();

}

 

 


Приложение 4. Библиотека управления консолью (MyCrt.h)

 

 

#include "stdafx.h"

#include <iostream>

#include <Windows.h>

 

using namespace std;

 

#pragma once;

 

short MaxX();

short MaxY();

void ConWidth(int W);

void ConHeight(int H);

void ConSize(int W, int H);

void ScrollVert(int P);

void ScrollHor(int P);

void ScrSize(int W, int H);

void ScrGoTo(int X, int Y);

void CursorVisible(bool Visible);

void GoToXY(short x, short y);

unsigned short WhereX();

unsigned short WhereY();

void WhereXY(unsigned short &x, unsigned short &y);

unsigned short GetTextColors();

void TextBackground(unsigned short Color);

void TextForeground(unsigned short Color);

void TextColor(unsigned short Colors);

void ChangeTextAttribute(unsigned short Attr, unsigned short x, unsigned short y, unsigned short len);

void ClrScr();

bool ReadKey(wchar_t &c);

 

 

HANDLE hMWin = GetStdHandle(STD_OUTPUT_HANDLE);

 

void ColorMap()

{

for (int i = 0; i < 16; ++ i)

{

int b = i << 4;

for (int f = 0; f < 16; ++ f)

{

SetConsoleTextAttribute(hMWin, b | f);

cout << '*';

}

cout << endl;

}

}

 

short MaxX()

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

return ConInfo.dwSize.X;

}

 

short MaxY()

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

return ConInfo.dwSize.Y;

}

 

void ConWidth(int W)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

COORD c = {W, ConInfo.dwSize.Y};

SetConsoleScreenBufferSize(hMWin, c);

}

 

void ConHeight(int H)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

if (H < 25)

H = 25;

COORD c = {ConInfo.dwSize.X, H};

SetConsoleScreenBufferSize(hMWin, c);

}

 

void ConSize(int W, int H)

{

if (H < 25)

H = 25;

COORD c = {W, H};

SetConsoleScreenBufferSize(hMWin, c);

}

 

void ScrSize(int W, int H)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

SMALL_RECT WRect = ConInfo.srWindow;

COORD c = GetLargestConsoleWindowSize(hMWin);

if (W > c.X)

W = c.X;

if (H > c.Y)

H = c.Y;

if (W > ConInfo.dwSize.X)

W = ConInfo.dwSize.X;

if (H > ConInfo.dwSize.Y)

H = ConInfo.dwSize.Y;

WRect.Right = WRect.Left + W - 1;

WRect.Bottom = WRect.Top + H - 1;

SetConsoleWindowInfo(hMWin, true, &WRect);

}

 

void ScrGoTo(int X, int Y)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

SMALL_RECT WRect = ConInfo.srWindow;

WRect.Right = X + WRect.Right - WRect.Left;

WRect.Bottom = Y + WRect.Bottom - WRect.Top;

WRect.Left = X;

WRect.Top = Y;

SetConsoleWindowInfo(hMWin, true, &WRect);

GoToXY(X, Y);

}

 

void ScrollVert(int P)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

SMALL_RECT WRect = ConInfo.srWindow;

WRect.Top += P;

WRect.Bottom += P;

SetConsoleWindowInfo(hMWin, true, &WRect);

GoToXY(WhereX(), WhereY() + P);

}

 

void ScrollHor(int P)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

SMALL_RECT WRect = ConInfo.srWindow;

WRect.Left += P;

WRect.Right += P;

SetConsoleWindowInfo(hMWin, true, &WRect);

GoToXY(WhereX() + P, WhereY());

}

 

void CursorVisible(bool Visible)

{

CONSOLE_CURSOR_INFO CursorInfo;

GetConsoleCursorInfo(hMWin, &CursorInfo);

CursorInfo.bVisible = Visible;

SetConsoleCursorInfo(hMWin, &CursorInfo);

}

 

void GoToXY(short x, short y)

{

COORD c = {x, y};

SetConsoleCursorPosition(hMWin, c);

}

 

unsigned short WhereX()

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

return ConInfo.dwCursorPosition.X;

}

 

unsigned short WhereY()

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

return ConInfo.dwCursorPosition.Y;

}

 

void WhereXY(unsigned short &x, unsigned short &y)

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

GetConsoleScreenBufferInfo(hMWin, &ConInfo);

x = ConInfo.dwCursorPosition.X;

y = ConInfo.dwCursorPosition.Y;

}

 

unsigned short GetTextColors()

{

CONSOLE_SCREEN_BUFFER_INFO ConInfo;

if (GetConsoleScreenBufferInfo(hMWin, &ConInfo))

return ConInfo.wAttributes;

else

return 0;

}

 

void TextBackground(unsigned short Color)

{

if (Color >= 16)

return;

Color = Color << 4;

Color = GetTextColors() & 0xFF0F | Color;

SetConsoleTextAttribute(hMWin, Color);

}

 

void TextForeground(unsigned short Color)

{

if (Color >= 16)

return;

Color = GetTextColors() & 0xFFF0 | Color;

SetConsoleTextAttribute(hMWin, Color);

}

 

void TextColor(unsigned short Colors)

{

if (Colors >= 256)

return;

SetConsoleTextAttribute(hMWin, Colors);

}

 

void ChangeTextAttribute(unsigned short Attr, unsigned short x, unsigned short y, unsigned short len)

{

COORD c = {x, y};

DWORD l;

FillConsoleOutputAttribute(hMWin, Attr, len, c, &l);

}

 

void ClrScr()

{

COORD c = {0, 0};

DWORD Chr;

CONSOLE_SCREEN_BUFFER_INFO ConInfor;

DWORD ConSize;

if (!GetConsoleScreenBufferInfo(hMWin, &ConInfor))

return;

ConSize = ConInfor.dwSize.X * ConInfor.dwSize.Y;

if (!FillConsoleOutputCharacter(hMWin, (TCHAR) ' ', ConSize, c, &Chr))

return;

if (!FillConsoleOutputAttribute(hMWin, ConInfor.wAttributes, ConSize, c, &Chr))

return;

SetConsoleCursorPosition(hMWin, c);

}

 

bool ReadKey(wchar_t &c)

{

bool b = 0;

c = _getwch();

if (c == 224 ||!c)

c = _getwch();

else

b = 1;

return b;

}

 


Приложение 5. Библиотека Menu.h и пример ее использования

 

Библиотека Menu.h

 

 

#include "MyCrt.h"

#include <string.h>

 

using namespace std;

 

#pragma once;

 

struct sMenu {

// Количество команд NumberComands <= 20; Текст команды <= 60 символов

int NormAttr; // Цвет не выбранного элемента меню

int ActiveAttr; // Цвет выбранного элемента меню

int SelectedComand; // Номер выбранного элемента меню (от 1 до NumberComands)

int NumberComands; // Количество элементов меню

wchar_t Comands[20][61]; // Тексты элементов меню

int X; // Положение меню на экране

int Y; // Положение меню на экране

};

 

int ComandMaxLen(sMenu &M)

// Возвращает длину самой длинной команды меню

{

size_t Max = wcslen(M.Comands[0]);

for (int i = 1; i < M.NumberComands; ++i)

if (wcslen(M.Comands[i]) > Max)

Max = wcslen(M.Comands[i]);

return Max;

}

 

void SetActiveComand(sMenu &M, short ActCom)

// Выделяет в меню выбранную команду

{

int CL = ComandMaxLen(M);

ChangeTextAttribute(M.NormAttr, M.X, M.Y + M.SelectedComand - 1, CL);

ChangeTextAttribute(M.ActiveAttr, M.X, M.Y + ActCom - 1, CL);

GoToXY(M.X + CL, M.Y + ActCom - 1);

M.SelectedComand = ActCom;

}

 

void DisplayMenu(sMenu &M, int X, int Y)

// Выводит меню на экран

{

M.X = X;

M.Y = Y;

for (int i = 0; i < M.NumberComands; ++i)

{

GoToXY(X, Y + i);

wcout << M.Comands[i] << endl;

}

SetActiveComand(M, M.SelectedComand);

}

 

int MenuNavigator(sMenu &M, int X, int Y, wchar_t &c)

// Осуществляет перемещение по меню и возвращает номер выбранной команды.

// Параметр "с" соответствует коду клавиши, с помощью которой была выбрана команда

{

CursorVisible(false);

DisplayMenu(M, X, Y);

do

{

if (!ReadKey(c))

{

if (c == 72) // Up

if (M.SelectedComand > 1)

SetActiveComand(M, M.SelectedComand - 1);

else

SetActiveComand(M, M.NumberComands);

if (c == 80) // Dn

if (M.SelectedComand < M.NumberComands)

SetActiveComand(M, M.SelectedComand + 1);

else

SetActiveComand(M, 1);

}

}

while (c!= 27 && c!= 13);

CursorVisible(true);

return M.SelectedComand;

}

 

int MenuChoice(sMenu &M, int X, int Y, wchar_t &c)

// Чистит экран и выводит меню в точку (X, Y)

{

ClrScr();

return MenuNavigator(M, X, Y, c);

}

 

int MenuChoice(sMenu &M, wchar_t &c)

{

// Экран не чистится. Выводит меню в точку, где находится курсор

return MenuNavigator(M, WhereX(), WhereY(), c);

}

 

Пример использования библиотеки Menu.h

 

// MenuExample.cpp: определяет точку входа для консольного приложения.

//

 

#include "stdafx.h"

#include <MyCrt.h>

#include <Menu.h>

 

using namespace std;

 

void InitMenu(sMenu &M)

{

sMenu B = {

0x9F, // Цвет не выбранного элемента меню

0x70, // Цвет выбранного элемента меню

1, // Начальный номер выбранного элемента меню

7, // Количество элементов меню

// Тексты элементов меню:

L" Команда 1 ",

L" Команда 2 ",

L" Команда 3 ",

L" Команда 4 ",

L" Команда 5 ",

L" Команда 6 ",

L" Выход "

};

M = B;

}

 

void InitMenu1(sMenu &M)

{

sMenu B = {

0x9F, // Цвет не выбранного элемента меню

0x70, // Цвет выбранного элемента меню

1, // Начальный номер выбранного элемента меню

2, // Количество элементов меню

// Тексты элементов меню:

L" Команда 31 ",

L" Команда 32 ",

};

M = B;

}

 

void ComandExecute1(int Com, wchar_t c)

{

switch (Com)

{

case 1:;

case 2:;

ClrScr();

cout << 3 << Com << " " << c << endl;

_getwch();

break;

}

}

 

void ComandExecute(int Com, wchar_t c)

{

switch (Com)

{

case 1:;

case 2:;

case 4:;

case 5:;

case 6:;

case 7:

ClrScr();

cout << Com << " " << c << endl;

_getwch();

break;

case 3:

sMenu M1;

InitMenu1(M1);

cout << "->";

Com = MenuChoice(M1, c);

if (c!= 27)

ComandExecute1(Com, c);

break;

}

}

 

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

{

setlocale (LC_ALL, ".866");

ConSize(80, 25);

ScrSize(80, 25);

TextColor(0x9F);

ClrScr();

sMenu M;

InitMenu(M);

wchar_t c;

int Key;

do

{

Key = MenuChoice(M, 20, 5, c);

if (c!= 27)

ComandExecute(Key, c);

}

while (Key!= 7);

return 0;

}

 

 


Поделиться с друзьями:

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.294 с.