Шрифт:
Интервал:
Закладка:
main( )
{
static char input[LIM][SIZE];
int ct = 0;
while(gets(input[ct]) != NUL && strcmp(input[ct].STOP) !=0
&& ct++ < LIM)
...
}
Программа прекращает чтение вводимой строки, если встречает символ EOF [в этом случае gets( ) возвращает NULL], или если вы нажимаете клавишу [ввод] в начале строки (т.e. введете пустую строку), или если вы достигли предела LIM. Чтение пустой строки дает пользователю простой способ прекращения ввода.
Давайте перейдем к последней из обсуждаемых нами функций, работающих со строками.
Функция strcpy( )
Мы уже говорили, что если pts1 и pts2 являются указателями строк, то выражение
pts2 = ptsl;
копирует только адрес строки, а не саму строку. Предположим, что вы все же хотите скопировать строку. В этом случае можно использовать функцию strcpy( ). Она работает примерно так:
/* демонстрация strcpy( ) */
#include <stdio.h>
#define WORDS "Проверьте, пожалуйста, вашу последнюю чапись."
main( ) {
static char *orig = WORDS;
static char copy [40];
puts(orig);
puts(copy);
strcpy(copy, orig);
puts(orig);
puts(copy);
}
Вот результат:
Проверьте, пожалуйста, вашу последнюю запись.
Проперьтe, пожалуйста, пашу последнюю запись.
Проверьте. пожалуйста, пашу последнюю запись.
Очевидно, что строка, на которую указывает второй аргумент (orig) функции strcpy( ), скопирована в массив, на который указывает первый аргумент (copy). Порядок аргументов функции такой же, как в операторе присваивания: строка, получающая значение, стоит слева. (Пустая строка является результатом печати массива copy до копирования, и она говорит о том, что статические массивы .инициализируются нулями, т. е. нуль-символами в символьном виде.)
Нужно обеспечить, чтобы размер массива, принимающего строку, был достаточен для ее размещения. Поэтому мы используем описание
static char copy [40];
а не
static char *copy; /* не выделяет память для строки */
Короче говоря, strcpy() требует два указателя строк в качестве аргументов. Второй указатель, ссылающийся на исходную строку, может быть объявленным указателем, именем массива или строковой константой. А первый указатель, ссылающийся на копию, должен ссылаться на массив или часть массива, имеющего размер, достаточный для размещения строки.
Теперь, когда мы описали несколько функций, работающих со строками, рассмотрим целую программу, работающую со строками.
ПРИМЕР: СОРТИРОВКА СТРОК
Возьмем реальную задачу сортировки строк в алфавитном порядке. Эта задача может возникнуть при подготовке списка фамилий, при создании алфавитного указателя и во многих других ситуациях. В такой программе одним из главных инструментов является функция strcmp( ), так как ее можно использовать для определения старшинства двух строк. Последовательность наших действий будет состоять из считывания массива строк, их сортировки и последующего вывода. Совсем недавно мы показали последовательность действий для считывания строк, и сейчас мы начнем программу таким же образом.
/* считывает строки и сортирует их */
#include <stdio.h>
#define SIZE 81 /* предельная длина строки, включая */
#define LIM 20 /* максимальное количество считываемых строк */
#define HALT " " /* нулевая строка для прекращения ввода */
main( )
{
static char input[LIM][SIZE]; /* массив для запоминания вводимых строк */
char *ptstr[LIM]; /* массив переменных типа указатель */
int ct = 0; /* счетчик вводимых строк */
int k; /* счетчик выводимых строк */
printf(" Введите до %d строк и я их отсортирую.n" , LIM);
printf(" Для прекращения ввода нажмите клавишу [ввод] в начале строки.n");
while((gets(input[ct])!= NULL) && strcmp(input[ct], HALT)
!= 0 && ct++ < LIM)
ptstr[ct - 1] = input[ct - 1]; /*указывает на еще не
отсортированный ввод */
stsrt(ptstr, ct); /* сортировка строк */
puts(" n Вот отсортированный список строк:n");
for(k = 0; k < ct; k++)
puts(ptstr[k]); /* указатели на отсортированные строки */
}
/* функция сортировки-строк-с-использованиeм-указатeлeй */
stsrt(strings, num)
char *strings[ ];
int num;
{ char *temp;
int top, seek;
for(top = 0; top < num-1; top++)
for(seek = top + 1; seek < num; seek++)
if(strcmp(strings[top], strings[seek]) > 0)
{ temp = strings [top];
strings [top] = strings [seek];
strings [seek] = temp;
} }
РИС. 13.4. Программа чтения и сортировки строк.
Вывод строк на печать не составляет проблемы, а для сортировки можно взять тот же алгоритм, который использовался раньше для чисел. Сейчас мы применим один хитрый трюк: посмотрим, сможете ли вы его заметить.
Для проверки возьмем детский стишок.
Введите 20 строк, и я их отсортирую.
Для прекращения ввода нажмите клавишу [ввод] в начале строки.
Жил на свете человек
Скрюченные ножки
И гулял он целый век
По скрюченной дорожке
Вот отсортированный список строк
Жил на свете человек
И гулял он целый век
По скрюченной дорожке
Скрюченные ножки
Детские стишки не кажутся слишком искаженными после сортировки их по алфавиту.
Трюк состоит в том что вместо перегруппировки самих строк мы перегруппировали их указатели. Разберемся в этом. В начале ptrst[0] ссылается на input[0] и т. д. Каждый input[ ] является массивом из 81 элемента, а каждый элемент ptrst[ ] является отдельной переменной. Процедура сортировки перегруппировывает ptrst, нe трогая input. Если, например, input[l] стоит перед input[0] по алфавиту, то программа переключает указатели ptrst, в результате чего ptrst[0] ссылается на input[1], a ptrst[1] на input[0]. Это гораздо легче, чем, используя strcpy( ), менять местами две введенные строки. Просмотрите еще раз этот процесс на рисунке.
И наконец, давайте попытаемся заполнить пробелы, оставшиеся в нашем описании, а именно "пустоту" между скобками в функции main( ).
АРГУМЕНТЫ КОМАНДНОЙ СТРОКИ
Командная строка - это строка, которую вы печатаете на клавиатуре, чтобы запустить вашу программу. Это нетрудно. Предположим, у нас есть программа в файле с именем fuss. В этом случае командная строка выглядела бы так:
РИС. 13.5. Указатели сортируемых строк.
или, может быть,
А > fuss
с использованием двух системных приглашений.
Аргументы командной строки являются дополнительными элементами в той же самой строке:
%fuss - r Ginger
Следует заметить, что программа на языке Си может вводить информацию в эти элементы и применять их для собственных нужд. Этот механизм предназначен для использования аргументов функции main( ). Вот типичный пример:
/* main( ) с аргументами */
main(argc, argv)
int argc;
char *argv[ ];
{
int count;
for(count = 1; count < argc; count++)
printf(" %s", argv[count]);
printf("n");
}
Поместите эту программу в выполняющий файл, названный echo, и вот что произойдет:
А > echo
Я мог бы воспользоваться небольшой помощью.
Я мог бы воспользоваться небольшой помощью.
Вероятно, вы видите, почему функция называется echo, но еще не можете понять, как она работает. Может быть, это объяснение поможет вам (мы надеемся).
Компиляторы Си предполагают наличие у main( ) двух аргументов. Первый аргумент представляет количество строк, следующих за командным словом. Обычно (но не обязательно) этот аргумент типа int называется argc (argument count). Система использует пробелы, чтобы сообщить о конце одной строки и начале следующей. Так, наш пример с echo имеет шесть строк, а пример с fuss имел две строки. Второй аргумент является массивом указателей строк. Каждой строке, входящей в командную строку, присваивается ее
- C++ - Страустрап Бьярн - Программирование
- Искусство программирования на языке сценариев командной оболочки - Мендель Купер - Программирование
- Delphi. Учимся на примерах - Сергей Парижский - Программирование