КИТ и Э КБГУ Вторник, 07.05.2024, 06:50
Приветствую Вас Гость | RSS
Меню сайта

Наш опрос
Оцените мой сайт
Всего ответов: 118

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Работа со сроками в Си/С++

  1. Ввод строк
  2. Функции работы со строками

     Практическая работа 5. Работа со строками

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

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

Ввод строк

Пример 1.

#include <stdio.h>

main()

{ char name[30];

printf("\n Как Вас зовут ? "); scanf("%s", name);

printf("Привет, %s\n", name); }

 

Замечание 1. Так как name является массивом символов, то значение name - это адрес самого массива. Поэтому в операторе scanf перед именем name не используется операция получения адреса &.

 

Пример 2.  /* Ввод строки с помощью функции gets */

#include <stdio.h>

main()

{ char name[40];

printf("\n Как Вас зовут (имя и фамилия через пробел) ? ");

gets(name);

printf("Здравствуйте, %s\n", name); }

Замечание 1. Функция gets читает все, что набирает пользователь, до тех пор, пока он не нажмет клавишу "Ввод". Код клавиши "Ввод" не помещается в строку, однако в конец строки добавляется нулевой символ '\0' */

Функции, для работы со строками

1 Связывание (конкатенация)

  1. strcat char *strcat(string1, string2) - добавляет копию строки string2 в конец строки string1.

Пример:

char str[80];

strcpy(str, "Heat");

strcat(str, "seeker");                     // теперь в str содержится "Heatseeker"

 

  1. strncat char *strncat(string1, string2, m) - добавляет копию m символов строки string2 в конец строки string1, и затем добавляет нулевой символ.

Пример:

char cMassiv[100];

char *szStr = "String1_";

strcpy(cMassiv, szStr);

char *szStr2 = "Noventa";

strncat(cMassiv, szStr2, 3);

printf("\ncMassiv = %s\n\n", cMassiv);  }               // сMassiv=String1_Nov

 

Обе функции возвращают ссылку на результат, то есть на строку string1. Эти функции не проверяют, умещается ли вторая строка в первой. Если Вы ошиблись при выделении памяти для первого массива, у Вас возникнут проблемы.

 

2 Сравнение

  1. strcmp int strcmp(string1, string2) - сравнивает string1 и string2

Пример:

int n = strcmp("Sink The Pink", "Stand Up");        

// n < 0, так как 'i' < 't', так как 105 < 116

 

  1. stricmp int stricmp(string1, string2) - сравнивает string1 и string2, не делая отличия между прописными и строчными буквами.

Пример:

int n = _stricmp("Danger", "danGer");                              // n == 0

 

  1. strncmp int strncmp(string1, string2, m) - производит такое же сравнение, как и stricmp, но просматривает не более, чем m символов.
  2. strnicmp int strnicmp (string1, string2, n) - сравнивает string1 и string2 (но не более, чем n байтов), не делая отличия между прописными и строчными буквами.

Все функции сравнения возвращают целое значение, меньшее, равное или большее нуля, в зависимости от результата лексикографического сравнения string1 со string2.

 

3 Копирование

  1. strcpy сhar *strcpy(string1, string2) - копирует string2 в строку string1 и останавливается после пересылки нулевого символа.

Пример:

char str[80];

strcpy(str, "Go Down");                        // теперь в str содержится "Go Down"

 

  1. strncpy char *strncpy(string1, string2, m) - копирует точно m символов из string2 в string1, усекая или заполняя нулевыми знаками string1, если это необходимо. Если длина строки string2 больше или равна m, результирующая строка не заканчивается нулевым знаком.

Обе функции возвращают ссылку на результат, то есть string1. Функции не проверяют, умещается ли вторая строка в первой.

 

4 Поиск

  1. strlen int strlen(string1) - возвращает число знаков в строке string1; нулевой знак, завершающий строку, не включается в это число.

Пример:

int n;

n = strlen("Overdose");                                   // n == 8

n = strlen("Dog\0Eat Dog");                                     // n == 3

 

  1. strchr char *strchr(string1, c) или strrchr char *strrchr(string1, c) - функция strchr(strrchr) возвращает указатель на первое (последнее) вхождение символа "c" в строку string1; если знак "c" не обнаружен в string1, то функция возвращает NULL. Нулевой знак, завершающий строку, является частью строки.

Пример:

char str[80];

strcpy(str, strchr("Overdose", 'd'));                          // теперь str содержит "dose"

 

  1. strpbrk char *strpbrk (string1, string2) - функция возвращает указатель на первый встретившийся в строке string1 знак строки string2 или NULL, если в строке string1 не встретилось ни одного знака строки string2.

 

  1. strspn int strspn(string1, string2); strcspn int strcspn(string1, string2) - функция strspn(strcspn) возвращает значение длины начального сегмента строки string1, целиком состоящего из знаков строки string2 (целиком состоящего из знаков, отсутствующих в строке string2).

 

  1. strtok char *strtok(string1, string2) - функция strtok рассматривает строку string1 как последовательность текстовых элементов (их число должно быть больше либо равно нулю), разделенных одним или более знаками из строки string2, выступающей в роли источника разделителей. Первый вызов функции (с заданным значением указателя string1 в качестве первого аргумента) возвращает указатель на первый знак первого элемента и записывает нулевой знак в строку string1 сразу после этого элемента.

Функция хранит информацию, необходимую для последующих вызовов (которые должны выполнятся со значением первого аргумента NULL), обеспечивающих обработку строки string1 со знака, непосредственно следующего за элементом строки, обработанным во время предыдущего вызова функции. Строка-разделитель string2 меняется от вызова к вызову. После того, как исчерпаны все элементы строки string1, функция возвращает значение указателя NULL.

 

5. Изменение

  1. strlwr char *strlwr(string1) - преобразует буквы верхнего регистра строки string1 в буквы нижнего регистра.
  2. strupr char *strupr(string1) - преобразует буквы нижнего регистра строки string1 в буквы верхнего регистра.
  3. strset char *strset(string1, ch) - устанавливает все символы строки string1 в символы ch.
  4. strnset char *strnset(string1, ch, n) - заменяет первые n байт строки string1 на символы ch. Если n>strlen(string1), то strlen(string1) принимает значение n.

 

Функции работы со строками - библиотека stdio.h

  1. int getchar() - возвращает значение символа, введенного вами с клавиатуры.

А вот и вывод этого числа: printf("%d", getchar());

 

  1. char *gets (char *s) - функция просит вводить пользователя строку, которую она помещает в массив s, пока пользователь не нажмет 'Enter':

Пример:

char str[7] = "";

gets(str) ;

  1. int putchar (int c) - печатает символ, который имеет код 'c':

Пример:  putchar(97);//напечатает символ а

 

  1. int puts (char *s) - печатает строку s и переводит курсор на новую строку:

Пример:

char str[7] = "sergey";

puts(str);

 

  1. int sprintf (char *s, char *format, ...) - Выполняет тоже, что и функция printf, за тем исключением, что записывает данные в массив s:

Пример:

char str[37] = "";

sprintf (str,"chislo:%d, month: %s",10,"desember"); //В массиве будет: chislo:10, month: desember

 

  1. int sscanf (char *s, char *format, ...) - происходит ввод значений не с клавиатуры, а из массива s:

Пример:

char str[37] = "sergey", s[100]="";

sscanf (str,"%s", s);

 

Функции преобразования данных

Заголовочный файл      #include <stdlib.h>

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

  1. int atoi( const char* str) - преобразует строковое представление целого числа str в двоичное и возвращает его. Преобразование прекращается на первом недопустимом символе; если такой символ окажется самым первым в строке, функция вернет значение 0.

Пример:

int x = atoi("28 bytes");

 

  1. long atol(const char* str) - под Win32 эта функция полностью аналогична atoi.

 

  1. long strtol( const char* str, char** end_ptr, int radix) -  преобразует строковое представление целого числа str в системе счисления с основанием radix в двоичное и возвращает его. При этом, в переменную по адресу end_ptr будет записан указатель на символ, который прервал обработку строки str.

Пример:

char str[80];

char* end_ptr;

puts("Enter your age:");

long age = strtol(gets(str), &end_ptr, 10);

if (*end_ptr != 0)

{   puts("oops!");

}

 

  1. double atof( const char* str) - преобразует строковое представление дробного числа str в двоичное и возвращает его. Преобразование прекращается на первом недопустимом символе; если такой символ окажется самым первым в строке, функция вернет значение 0.0. Заметим, что исходная строка может содержать как десятичное, так и экспоненциальное представление дробного числа.

 

  1. double strtod( const char* str, char** end_ptr) - преобразует строковое представление дробного числа str в двоичное и возвращает его, записывая по адресу end_ptr указатель на символ, который прервал обработку строки str. Использование этой функции аналогично strtol.

 

  1. char* _itoa( int number, char* dest, int radix) - записывает по адресу dest строковое представление целого числа number по основанию radix и возвращает dest.

Пример:

char dec_str[80];

char hex_str[80];

_itoa(13, dec_str, 10);            // теперь в dec_str содержится "13"

_itoa(13, hex_str, 16);            // теперь в hex_str содержится "d"

 

  1. char* _ltoa( long number, char* dest, int radix) - под Win32 эта функция полностью аналогична _itoa.

 

  1. char* _ultoa( unsigned long number, char* dest, int radix) - аналогична функции _ltoa, но предназначена для преобразования беззнаковых целых чисел.

 

  1. char* _gcvt( double number, int num_dig, char* dest) - записывает по адресу dest строковое представление дробного числа number и возвращает dest. Через параметр num_dig необходимо передать требуемое число знаков строкового представления. Заметим, что если данная функция не сможет представить исходное число в десятичной форме с требуемым количеством знаков, то будет выбрана экспоненциальная форма. При преобразовании в десятичную форму, функция отбрасывает незначащие нули.

 

  1. char* _fcvt( double number, int num_dec, int* dec_pos, int* has_sign)

Возвращает адрес буфера, содержащего строковое представление дробного числа number в десятичной форме; заметим, что этот буфер перезаписывается при каждом вызове функции. Через параметр num_dec необходимо передать требуемое количество десятичных знаков; при необходимости исходное число будет округлено или дополнено нулями. В переменную по адресу dec_pos будет записана требуемая позиция десятичной точки в возвращенной строке; при этом, если целая часть числа равна 0, то по этому адресу будет записано отрицательное или нулевое значение. В переменную по адресу has_sign записывается ненулевое значение для отрицательного исходного числа и 0 — в противном случае.

Таким образом, возвращаемая данной функцией строка не содержит ни знака, ни десятичной точки.

Пример:

char str[80];

int dec_pos;

int has_sign;

strcpy(_fcvt(3.85, 3, &dec_pos, &has_sign));                               // теперь в str содержится "3850", dec_pos == 1,  has_sign == 0

strcpy(_fcvt(-21.6, 1, &dec_pos, &has_sign));                             // теперь в str содержится "216", dec_pos == 2,  has_sign != 0

strcpy(_fcvt(-0.013, 3, &dec_pos, &has_sign));                           // теперь в str содержится "013",  dec_pos <= 0, has_sign != 0

 

 

  1. char* _ecvt( double number, int num_dec, int* dec_pos, int* has_sign) - данная функция полностью аналогична _fcvt, за исключением того, что исходное число представляется в экспоненциальной форме. Заметим, что эта функция использует тот же буфер, что и _fcvt.

 

Пример 1.

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

Разбор задачи. Сначала необходимо запросить у пользователя строку, ввести ее с клавиатуры. Затем в цикле, начиная с первого символа, проверять, равен ли текущий символ символу х, если да, символы равны, увеличить специальную переменную-счетчик на 1, иначе перейти к анализу следующего символа и так до конца строки. В конце вывести результат (значение переменной-счетчика) на экран. Замечание: не забудьте обнулить значение счетчика перед использованием.

 

#include <iostream.h>

void main( void )

 char str[100]; // объявление строки символов

cout << "\nInput a string: ";

 cin >> str; // считываем строку, введенную пользователем

 int count = 0;

/* объявление переменной-счетчика, в которой будем хранить количество вхождений х в строку */

 // в цикле сравниваем каждый символ строки с х-ом, в случае совпадения увеличиваем переменную-счетчик на 1.

 int i = 0;

 while(str[i] != '\0')

 if (str[i] == 'x') count++;

 // выводим результат на экран

 cout << "\n Number of x is " << count;

Пример 2.

Написать программу, которая получает от пользователя набор символов, исключая пробел, и удаляет из этого набора все вхождения символов S и s.

Разбор задачи. Из условия задачи можно сделать следующие выводы: мы должны написать программу, которая при получении конкретного набора символов должна произвести проверку этого набора на наличие символов S и s. Если символ S(или s) встретится в наборе, то необходимо его удалить из этого набора. Конечный результат не должен содержать ни одного символа S и s.

Решение задачи будет состоять из трех блоков:

  1. получение данных от пользователя (т.е. пользователь должен ввести строку для обработки),
  2. анализ строки на наличие символов S и s,
  3. вывод результата.

Для нас наибольший интерес представляет этап анализа строки. Для реализации этого этапа нам нужно поэлементно двигаться от нулевого индекса массива к последнему и делать проверку каждого элемента. Если будет встречен такой элемент с индексом i, то нам нужно сместить все элементы с индексами большими чем i на один индекс меньше. Другими словами:

Пускай дана следующая строка:

A b s D e f

0 1 2 3 4 5 ------ индексы

Проверяя по индексно каждый элемент массива, находим, что 2 элемент массива и есть искомый символ. Тогда, нам нужно сместить каждый элемент массива на 1 индекс меньше, т.е. мы получим следующий результат:

A b D e f

0 1 2 3 4

и тем самым добьемся решения задачи.

Реализация сказанного приведена ниже на С++.

#include <iostream.h>

void main()

 const int CharCount=10;     //зададим размерность массива через константу

 char arr[CharCount];           //объявление символьного массива

           //Предупредим пользователя, что ввод ограничен размерностью массива

 cout << "\nDo enter any string but no more then "

 << CharCount-1 << " symbols\n";

 cin >> arr;                       // ввод строки

 int i=0;

 while (arr[i]!='\0')              /* Цикл работает пока не встретится признак конца строки */

 if (arr[i]=='S'||arr[i]=='s')    //Проверка на искомый символ

 { /*Если это искомый символ, то перенесем оставшуюся часть строки на один элемент левее...*/

 for (int j=i;arr[j]!='\0';j++)

 arr[j]=arr[j+1];

 }

 else i++;                                 /*..., а если это не искомый символ, то будем двигаться по нашему массиву дальше */

 cout << endl << arr << endl;   /* опять таки, помним, что нужно вывести результат */

Пример 3.  Написать программу сравнения двух строк.

Разбор задачи. Чтобы понять, что означает одна строка "больше" или "меньше", чем другая строка, рассмотрим процесс расстановки имен по алфавиту. Вы, без сомнения, поставили бы "Jones" перед "Smith", потому что в алфавите J раньше S. Но как компьютер узнает о порядке следования букв? Помните? - все символы представляются внутри компьютера как численные коды; когда компьютер сравнивает две строки, он на самом деле сравнивает численные коды символов в строке. (Замечание: коды символов упорядочены по алфавиту только для латинских букв, к кириллице это, к сожалению, не относится)

Перед тем как перейти непосредственно к программе, сделаем еще одно примечание. В некоторых случаях желательно вводить в массив полную строку текста. С этой целью C++ снабжен функцией cin.getline. Функция cin.getline требует три аргумента - массив символов, в котором должна храниться строка текста, длина и символ ограничитель. Например, фрагмент программы

 

 char sentence[80];

 cin.getline(sentence, 80, '\n');

объявляет массив sentence из 80 символов, затем считывает строку текста с клавиатуры в этот массив. Функция прекращает считывание символов в случаях, если встречается символ-ограничитель '\n', если вводится указатель конца файла или если количество считанных символов оказывается на один меньше, чем указано во втором аргументе (последний символ в массиве резервируется для завершающего нулевого символа). Если встречается символ ограничитель, он считывается и отбрасывается. Третий аргумент cin.getline имеет '\n' в качестве значения по умолчанию, так что предыдущий вызов функции мог быть написан в следующем виде:

 cin.getline(sentence, 80);

​void main()

 int len;           // длина вводимой строки

 char s[81];     // место хранения вводимой строки

 char *s1,*s2;

 

cout << "Input the first string: ";

cin.getline(s, 80);                                                         // ввод первой строки

len = strlen(s);                                                            // определение длины строки

s1 = new char[ len + 1];                                              // динамическое выделение памяти под строку s1

strcpy(s1, s);                                                            // копирование введенной строки в строку s1

cout << "Input the second string: ";

cin.getline(s, 80);                                                      // ввод второй строки

len = strlen(s);

s2 = new char[len + 1];                                            // динамическое выделение памяти под строку s2

strcpy(s2, s);

                                                                            // какая из введенных строк больше?

if(strcmp(s1, s2) > 0)

 cout << "String s1:\t" << s1 << "\n\t > \n"

 << "String s2:\t"

 << s2 << endl;

 else if(strcmp(s1, s2) == 0)

 cout << "String s1:\t" << s1 << "\n\t=\n"

 << "String s2:\t"

 << s2 << endl;

 else

 cout << "String s1:\t" << s1 << "\n\t < \n"

 << "String s2:\t"

 << s2 << endl;

                                                                                  // удаление строк из памяти

 delete []s1;

 delete []s2;

Вход на сайт

Поиск

Календарь
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031

Архив записей

Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Copyright Fatima_Zh © 2024Бесплатный хостинг uCoz