str, останется без изменения. Значение NULL является возвращаемым значением и в том случае, когда будет обнаружена ошибка чтения, но в этом случае содержимое массива считается не определенным. Приведем пример применения функции gets(). В этом примере вначале запрашивается имя
пользователя, а затем компьютер выводит приветствие.
/* Greeting.c */ #include<stdio.h> #include<string.h> #define MAX 81
int main(void)
{
char name[MAX];
char out[MAX] = “Привет, Вам ”; puts(“Введите Ваше имя”); gets(name);
printf(“Привет, Вам %s”, name);
puts(out); return 0;
}
Протокол работы с программой greeting имеет следующий вид Введите Ваше имя
Иван Привет, Вам Иван
Существенным недостатком рассматриваемой функции является возможность переполнения массива, на который установлен указатель str. В связи с этим функцию gets() не рекомендуют использовать в коммерческих приложениях. Для этих целей можно воспользоваться функцией fgets().
В связи с тем, что функция gets() пользуется плохой репутацией, в качестве альтернативы этой функции предлагается использовать функцию файлового ввода-вывода fgets().Для обсуждения возможности использования
этой функции для консольного ввода приведем прототип функции fgets():
#include<stdio.h>
char* fgets(char* str, int n, FILE* stream);
Рассматриваемая функция имеет два дополнительных параметра, которые отсутствуют у функции gets(). Первый из дополнительных параметров (int n) служит для ограничения количества символов, которые могут быть прочитаны в массив str из буфера клавиатуры. Второй дополнительный параметр (FILE stream) при использовании функции fgets() определяет файл, с которым должна работать эта функция. Для консольного ввода достаточно в ее вызове в качестве параметра stream взять имя стандартного потока, предназначенного для работы с клавиатурой (stdin).
Функция fgets() в форме, предназначенной для ввода с клавиатуры, позволяет записать в массив, на который указывает указатель str, не более n – 1 символа. Ввод прекращается, как только встретится символ новой
111
строки (который записывается в массив) или символ конца файла. За последним введенным символом добавляется нуль-символ. В случае успешного завершения функция вернет указатель строку str. Если прочитан конец файла, а ни один символ не был введен, то содержимое массива оказывается неизменным, а функция вернет значение NULL. Если во время ввода имела место ошибка, то функция вернет значение NULL, а содержимое массива str оказывается неопределенным. Приведем пример.
#include<stdio.h>
#include<string.h> #define MAXSIZE 81
int main(void) |
|
|
|
{ |
|
|
|
char buf[MAXSIZE]; |
|
|
|
char* s = NULL; |
|
|
|
fgets(buf, sizeof(buf), stdin); |
|||
s = strchr(buf, '\n');/* |
Ищем символ ‘\n’ в прочитанной |
||
if(s != NULL) |
|
строке */ |
|
/* |
Запись символа ‘\0’вместо |
||
*s = '\0'; |
|||
return 0; |
|
символа ‘\n’ */ |
|
|
|
||
}
С целью приблизить работу функции fgets() к работе функции gets(), которую она призвана заменить, в рассматриваемом примере добавлен программный код, удаляющий из массива, используемого для ввода строки (buf), символ новой строки (\n). Для этой цели используется функция strchr() и инструкция if.
Для ввода строк с клавиатуры можно воспользоваться следующими библиотечными функциями:
∙printf(),
∙puts(),
∙fputs().
Начнем рассмотрение с функции printf().
Строки могут выводиться с помощью библиотечной функции printf(). Для вывода строкового литерала достаточно поместить его текст в форматной строке вызова рассматриваемой функции. Пусть необходимо вывести стандартное приветствие. Это можно выполнить с помощью
следующего вызова функции printf(): printf(“Hello, world”);
112
В более сложных случаях следует при выводе строк использовать спецификацию типа s. В качестве примера приведем вывод заголовка
таблицы:
printf(“%5s%10s%10s”, “НОМЕР”, “АРГУМЕНТ”, “ФУНКЦИЯ”);
Объявление функции puts() имеет следующий вид
#include<stdio.h>
int puts(const char* str);
Функция puts() выводит на экран дисплея строку, на которую установлен указатель str. Нуль – символ этой строки преобразуется в символ новой строки, который выводится на экран. Последнее приводит к тому, что после вывода строки str курсор перейдет на начало новой строки экрана.
При успешном выполнении функция puts() возвращает неотрицательное число, а в случае сбоя – значение EOF.
Рекомендуется использовать функцию puts() вместо printf() в тех случаях, когда необходимо вывести отдельное сообщение для пользователя, которое не сопровождается выводом и вводом данных.
Приведем пример применения функции puts().
/* Демонстрация вывода строк с применением функции puts()*/ /* Файл puts.c */
#include<stdio.h> int main(void)
{ |
msg1 |
= “Не”; |
char* |
||
char* |
msg2 |
= “применяйте”; |
char* |
msg3 |
= “функцию”; |
char* |
msg4 |
= “gets()”; |
char* |
msg5 |
= “в коммерческих”; |
char* |
msg6 |
= “приложениях!!!”; |
puts(msg1); |
|
|
puts(msg2); |
|
|
puts(msg3); |
|
|
puts(msg4); |
|
|
puts(msg5); |
|
|
puts(msg6); |
|
|
return |
0; |
|
}
Результат выполнения программы будет иметь следующий вид: Не применяйте функцию
gets()
в коммерческих приложениях!!!
113
Функция fputs() предназначена для работы с файлами. Она не имеет особых преимуществ перед функцией puts(), которая используется для консольного вывода строк. Ее целесообразно применять совместно с функцией ввода строк fgets(). Функция fgets() имеет очевидные преимущества перед функцией gets(), специально предназначенной для консольного ввода строк. Это и делает оправданным рассмотрение этой функции.
Прототип рассматриваемой функции имеет следующий вид:
#include<stdio.h>
int fputs(const char*s, FILE* stream);
Рассматриваемая функция имеет один дополнительный параметр, которого нет у функции puts().Этот дополнительный параметр (FILE stream) при использовании функции fgets() определяет файл, с которым должна работать эта функция. Для консольного ввода достаточно в ее вызове в качестве параметра stream взять имя стандартного потока, предназначенного для работы с клавиатурой (stdout).
Эта функция (в том случае, когда она вызвана со вторым параметром, равным stdout), выводит на экран дисплея строку символов, на которую установлен указатель s. При этом нуль-символ, которым заканчивается выводимая строка отбрасывается. В отличие от puts() функция fputs() не дополняет выводимую строку символом “новая строка”. Если во время вывода строки имеет место ошибка, то функция fputs() вернет значение EOF. При успешном завершении рассматриваемой функции возвращается неотрицательное число.
Эта функция предназначена для определения длины строки. Ее прототип имеет следующий вид:
#include<string.h>
size_t strlen(const char* str);
Тип size_t является разновидностью целочисленного типа. Функция strlen() возвращает длину строки, на которую установлен указатель str, причем строка должна заканчиваться “нуль – символом”. “Нуль – символ” во время определения длины строки не учитывается. Пример применения
функции strlen().
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main(void)
{
clrscr(); char str[81];
printf(“Введите строку:”);
114
gets(str);
printf(“Длина введенной строки =%d”, strlen(str));
getch(); return 0;
}
Протокол работы с программой имеет следующий вид. Введите строку:Это строка
Длина введенной строки=10
Прежде всего, следует отметить, что в языке См отсутствуют встроенные средства для копирования строк. Применять для этой цели оператор присваивания нельзя. При компиляции приведенного ниже кода будет выдано сообщение об ошибке.
/* |
Программный код, содержащий ошибку |
*/ |
char |
str1[30] = “Hello”; |
|
char |
str2[30]; |
|
str2 = str1; указатель
Для копирования строк в языке Си следует использовать библиотечные функции strcpy() и strncpy(). Обращает на себя похожесть имен этих функций. В соответствии с принципом образования имен, принятым в библиотеке string это означает, что функция strncpy() имеет дополнительный параметр n.
Объявления функций strcpy() и strncpy() имеют следующий вид:
#include<string.h>
char* strcpy(char* out_str, const char* in_str);
char* strncpy(char* out_str, const char* in_str, size_t n);
Обе функции (strcpy() и strncpy) копируют содержимое строки in_str в строку out_str. Параметр in_str должен указывать на строку, которая заканчивается нуль - символом. До вызова рассматриваемых функций необходимо выделить память для хранения новой строки. Функции strcpy() и strncpy() эту память не выделяют. Обе функции возвращают значение указателя out_str. Обе функции заканчивают копирование в том случае, когда в строке str_in встречается нуль – символ. Функция strncpy() выполняет копирование более осторожным образом. Это связано с наличием у этой функции третьего параметра (параметр n), который ограничивает количество копируемых символов. Количество символов, которые могут быть скопированы функцией strncpy() не может быть больше n. Заметим, что в предельном случае, когда в скопированных n символах строки in_str не встретился нуль \ символ, то выходная строка не будет заканчиваться нуль – символом. Если массивы in_str и out_str перекрываются поведение функции strcpy() не определено.
115