Копирование строк си. Операции со строками

Объявление строк

Строка в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string).

Объявление переменной типа строка в языке Си возможно тремя способами, два из которых инициализируют строку во время объявления.

Первый способ:

Объявления массива символов (не забудьте добавить место для завершающего нуля):

Char s;

Второй способ:

Присвоить строковой переменной начальное значение (при этом длину строки компилятор может вычислить сам):

Char s = "Пример инициализации строки";

Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль (‘\0’). Константы символьных строк помещаются в класс статической памяти.

Третий способ:

Неявное указание, что используется массив. В левой части от знака присваивания указывается указатель на символ:

Char *s="Второй вариант инициализации";

Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено:

Char *s;

Ввод строки со стандартного устройства ввода (клавиатуры)

Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets .

Для ввода строки с помощью функции scanf , использует формат «%s » , причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «& » , так как одномерный массив уже представлен указателем на его начало:

Scanf("%s", s);

Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль (‘\0’). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:

#include int main() { char s; char *p; p=gets(s); printf(" \n Введена строка %s. ",s); if (p) printf(" \n Введена строка %s. ",p); return 0; }

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

#include #include #include int main() { char s; int x, err; do { printf(" \n Введите целое число -> "); gets(s); err=sscanf(s, "%d",&x); if (err!=1) printf(" \n Ошибка ввода. "); } while (err!=1); printf("\n Введено целое число -> %d", x); return 0; }

Вывод строк на стандартное устройство вывода (экран монитора)

Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts . В функции printf в качестве формата передается «%s». Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку.

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

Для преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип).

Наиболее используемые функции рассмотрены в этой статье. — читать

Пример программ(листинг) работающей со строками

Теги: Си строки. Char array.

Строки в си. Введение.

Э то вводная статья по строкам в си. Более подробное описание и примеры будут, когда мы научимся работать с памятью и указателями. В компьютере все значения хранятся в виде чисел. И строки тоже, там нет никаких символов и букв. Срока представляет собой массив чисел. Каждое число соответствует определённому символу, который берётся из таблицы кодировки. При выводе на экран символ отображается определённым образом.
Для хранения строк используются массивы типа char. Ещё раз повторюсь – тип char – числовой, он хранит один байт данных. Но в соответствии с таблицей кодировки каждое из этих чисел связано с символом. И в обратную сторону – каждый символ определяется своим порядковым номером в таблице кодировки.
Например

#include #include void main() { char c = "A"; int i = 65; printf("display as char %c\n", c); printf("display as int %d\n", c); printf("display as char %c\n", i); printf("display as char %d\n", i); getch(); }

Мы создали две переменные, одна типа char , другая int . Литера "A" имеет числовое значение 65. Это именно литера, а не строка, поэтому окружена одинарными кавычками. Мы можем вывести её на печать как букву

Printf("display as char %c\n", c);

Тогда будет выведено
A
Если вывести её как число, то будет
65
Точно также можно поступить и с числом 65, которое хранится в переменной типа int .
Спецсимволы также имеют свой номер

#include #include void main() { printf("%c", "\a"); printf("%d", "\a"); printf("%c", 7); getch(); }

Здесь будет сначала "выведен" звуковой сигнал, затем его числовое значение, затем опять звуковой сигнал.
Строка в си – это массив типа char , последний элемент которого хранит терминальный символ "\0". Числовое значение этого символа 0, поэтому можно говорить, что массив оканчивается нулём.
Например

#include #include void main() { char word; word = "A"; word = "B"; word = "C"; word = "\0"; //word = 0; эквивалентно printf("%s", word); getch(); }

Для вывода использовался ключ %s. При этом строка выводится до первого терминального символа, потому что функция printf не знает размер массива word.
Если в этом примере не поставить

Word = "\0";

то будет выведена строка символов произвольной длины, до тех пор, пока не встретится первый байт, заполненный нулями.

#include #include void main() { char word = "ABC"; char text = {"H", "E", "L", "L", "O"}; printf("%s\n", word); printf("%s", text); getch(); }

В данном случае всё корректно. Строка "ABC" заканчивается нулём, и ею мы инициализируем массив word. Строка text инициализируется побуквенно, все оставшиеся символы, как следует из главы про массивы, заполняются нулями.

Чтение строк

Д ля того, чтобы запросить у пользователя строку, необходимо создать буфер. Размер буфера должен быть выбран заранее, так, чтобы введённое слово в нём поместилось. При считывании строк есть опасность того, что пользователь введёт данных больше, чем позволяет буфер. Эти данные будут считаны и помещены в память, и затрут собой чужие значения. Таким образом можно провести атаку, записав нужные байты, в которых, к примеру, стоит переход на участок кода с вредоносной программой, или логгирование данных.

#include #include void main() { char buffer; scanf("%19s", buffer); printf("%s", buffer); getch(); }

В данном случае количество введённых символов ограничено 19, а размер буфера на 1 больше, так как необходимо хранить терминальный символ. Напишем простую программу, которая запрашивает у пользователя строку и возвращает её длину.

#include #include void main() { char buffer; unsigned len = 0; scanf("%127s", buffer); while (buffer != "\0") { len++; } printf("length(%s) == %d", buffer, len); getch(); }

Так как числовое значение символа "\0" равно нулю, то можно записать

While (buffer != 0) { len++; }

Или, ещё короче

While (buffer) { len++; }

Теперь напишем программу, которая запрашивает у пользователя два слова и сравнивает их

#include #include /* Результатом сравнения будет число 0 если слова равны 1 если первое слово больше второго в лексикографическом порядке -1 если второе слово больше */ void main() { char firstWord; //Первое слово char secondWord; //Второе слово unsigned i; //Счётчик int cmpResult = 0; //Результат сравнения scanf("%127s", firstWord); scanf("%127s", secondWord); for (i = 0; i < 128; i++) { if (firstWord[i] > secondWord[i]) { //Больше даже если второе слово уже закончилось, потому что //тогда оно заканчивается нулём cmpResult = 1; break; } else if (firstWord[i] < secondWord[i]) { cmpResult = -1; break; } } printf("%d", cmpResult); getch(); }

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

 Строка – это последовательность ASCII или UNICODE символов. Строки в си , как и в большинстве языков программирования высокого уровня рассматриваются как отдельный тип, входящий в систему базовых типов языка. Так как язык СИ по своему происхождению является языком системного программирования, то строковый тип данных в нем как таковой отсутствует, а в качестве строк в си используются обычные массивы символов.
 Исторически сложилось два представления формата строк:
  1. формат ANSI;
  2. строки с завершающим нулем (используется в СИ).

Формат ANSI устанавливает, что значением первой позиции в строке является ее длина, а затем следуют сами символы строки. Например, представление строки "Моя строка!" будет следующим:
  11 ‘М’ ‘о’ ‘я’ ‘ ’ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’
 В строках с завершающим нулем, значащие символы строки указываются с первой позиции, а признаком завершения строки является значение ноль. Представление рассмотренной ранее строки в этом формате имеет вид:
  ‘М’ ‘о’ ‘я’ ‘ ’ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’ 0

Объявление строк в СИ


 Строки реализуются посредством массивов символов. Поэтому объявление ASCII строки имеет следующий синтаксис:
  char имя[длина];  Объявление строки в си имеет тот же синтаксис, что и объявление одномерного символьного массива. Длина строки должна представлять собой целочисленное значение (в стандарте C89 – константа, в стандарте C99 может быть выражением). Длина строки указывается с учетом одного символа на хранение завершающего нуля, поэтому максимальное количество значащих символов в строке на единицу меньше ее длины. Например, строка может содержать максимально двадцать символов, если объявлена следующим образом:
  char str;  Инициализация строки в си осуществляется при ее объявлении, используя следующий синтаксис:
  char str[длина] = строковый литерал;  Строковый литерал – строка ASCII символов заключенных в двойные кавычки. Примеры объявления строк с инициализацией:
  char str1 = "Введите значение: ", str2 = "";  Пример:
  const char message = "Сообщение об ошибке!";

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


 Так как строки на языке СИ являются массивами символов, то к любому символу строки можно обратиться по его индексу. Для этого используется синтаксис обращения к элементу массива, поэтому первый символ в строке имеет индекс ноль. Например, в следующем фрагменте программы в строке str осуществляется замена всех символов ‘a’ на символы ‘A’ и наоборот.
  for(int i=0;str[i]!=0;i++)
  {
   if(str[i] == ‘a’) str[i] = ‘A’;
    else if(str[i] == ‘A’) str[i] = ‘a’;
  }

Массивы строк в СИ


 Объявление массивов строк в языке СИ также возможно. Для этого используются двумерные массивы символов, что имеет следующий синтаксис:
 char имя[количество][длина];  Первым размером матрицы указывается количество строк в массиве, а вторым – максимальная (с учетом завершающего нуля) длина каждой строки. Например, объявление массива из пяти строк максимальной длиной 30 значащих символов будет иметь вид:
  char strs;  При объявлении массивов строк можно производить инициализацию:
  char имя[количество][длина] =
   {строковый литерал №1, ... строковый литерал №N};
 Число строковых литералов должно быть меньше или равно количеству строк в массиве. Если число строковых литералов меньше размера массива, то все остальные элементы инициализируются пустыми строками. Длина каждого строкового литерала должна быть строго меньше значения длины строки (для записи завершающего нуля).
Например:
  char days = {
   "Январь", "Февраль", "Март", ”Апрель", "Май",
   "Июнь", "Июль", "Август", "Сентябрь","Октябрь",
   "Ноябрь", "Декабрь"
  };
 При объявлении массивов строк с инициализацией допускается не указывать количество строк в квадратных скобках. В таком случае, количество строк в массиве будет определено автоматически по числу инициализирующих строковых литералов.
Например, массив из семи строк:
  char days = {
   "Понедельник", "Вторник", "Среда", "Четверг",
   "Пятница", "Суббота", "Воскресенье"
  };

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


 Все библиотечные функции, предназначенные для работы со строками, можно разделить на три группы:
  1. ввод и вывод строк;
  2. преобразование строк;
  3. обработка строк.

Ввод и вывод строк в СИ


 Для ввода и вывода строковой информации можно использовать функции форматированного ввода и вывода (printf и scanf). Для этого в строке формата при вводе или выводе строковой переменной необходимо указать спецификатор типа %s. Например, ввод и последующий вывод строковой переменной будет иметь вид:
  char str = "";
  printf("Введите строку: ");
  scanf("%30s”,str);
  printf("Вы ввели: %s”,str);
 Недостатком функции scanf при вводе строковых данных является то, что символами разделителями данной функции являются:
  1. перевод строки,
  2. табуляция;
  3. пробел.
Поэтому, используя данную функцию невозможно ввести строку, содержащую несколько слов, разделенных пробелами или табуляциями. Например, если в предыдущей программе пользователь введет строку: "Сообщение из нескольких слов", то на экране будет выведено только "Сообщение".
 Для ввода и вывода строк в библиотеке stdio.h содержатся специализированные функции gets и puts.

Функция gets предназначена для ввода строк и имеет следующий заголовок:
  char * gets(char *buffer);

 Функция puts предназначена для вывода строк и имеет следующий заголовок:
  int puts(const char *string);  Простейшая программа: ввод и вывод строки с использованием функций gets и puts будет иметь вид:
  char str = "";
  printf("Введите строку: "); gets(str);
  printf("Вы ввели: ");
  puts(str);
 Помимо функций ввода и вывода в потоки в библиотеке stdio.h присутствуют функции форматированного ввода и вывода в строки. Функция форматированного ввода из строки имеет следующий заголовок:
  int sscanf(const char * restrict buffer,const char * restrict string, ...);  Функции форматированного вывода в строку имеют следующие заголовки:
  int sprintf(char * restrict buffer,

  int snprintf(char * restrict buffer, size_t maxsize,
  const char * restrict format, ...);

Преобразование строк


 В СИ для преобразования строк, содержащих числа, в численные значения в библиотеке stdlib.h
предусмотрен следующий набор функций:
  double atof(const char *string); // преобразование строки в число типа double
  int atoi(const char *string); // преобразование строки в число типа int
  long int atol(const char *string); // преобразование строки в число типа long int
  long long int atoll(const char *string); // преобразование строки в число типа long long   int
 Корректное представление вещественного числа в текстовой строке должно удовлетворять формату:
  [{+|-}][цифры][.цифры][{e|E}[{+|-}]цифры]

После символов E, e указывается порядок числа. Корректное представление целого числа в текстовой строке должно удовлетворять формату:
   [{+|-}] цифры

Помимо приведенных выше функций в библиотеке stdlib.h доступны также следующие функции преобразования строк в вещественные числа:
  float strtof(const char * restrict string, char ** restrict endptr);
  double strtod(const char * restrict string, char ** restrict endptr);
  long double strtold(const char * restrict string,char ** restrict endptr);

Аналогичные функции присутствуют и для преобразования строк в целочисленные значения:
  long int strtol(const char * restrict string,

  unsigned long strtoul(const char * restrict string,
  char ** restrict endptr, int base);
  long long int strtoll(const char * restrict string,
  char ** restrict endptr, int base);
  unsigned long long strtoull(const char * restrict string,char ** restrict endptr, int base);

Функции обратного преобразования (численные значения в строки) в библиотеке stdlib.h присутствуют, но они не регламентированы стандартом, и рассматриваться не будут. Для преобразования численных значений в строковые наиболее удобно использовать функции sprintf и snprintf.

Обработка строк


 В библиотеке string.h содержаться функции для различных действий над строками.
Функция вычисления длины строки:
  size_t strlen(const char *string); Пример:
  char str = "1234";
  int n = strlen(str); //n == 4
 Функции копирования строк:
  char * strcpy(char * restrict dst, const char * restrict src);
  char * strncpy(char * restrict dst, const char * restrict src, size_t num);
 Функции сравнения строк:
  int strcmp(const char *string1, const char *string2);
  int strncmp(const char *string1, const char *string2,size_t num);
 Функции осуществляют сравнение строк по алфавиту и возвращают:
  положительное значение – если string1 больше string2;
  отрицательное значение – если string1 меньше string2;
  нулевое значение – если string1 совпадает с string2;

Функции объединения (конкатенации) строк:
  char * strcat(char * restrict dst, const char * restrict src);
  char * strncat(char * restrict dst, const char * restrict src, size_t num);

Функции поиска символа в строке:
  char * strchr(const char *string, int c);
  char * strrchr(const char *string, int c);

Функция поиска строки в строке:
  char * strstr(const char *str, const char *substr);

Пример:
  char str = "Строка для поиска";
  char *str1 = strstr(str,"для"); //str1 == "для поиска"

Функция поиска первого символа в строке из заданного набора символов:
  size_t strcspn(const char *str, const char *charset);

Функции поиска первого символа в строке не принадлежащему заданному набору символов:
  size_t strspn(const char *str, const char *charset);

Функции поиска первого символа в строке из заданного набора символов:
  char * strpbrk(const char *str, const char *charset);

Функция поиска следующего литерала в строке:
  char * strtok(char * restrict string, const char * restrict charset);

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

Что такое строки?

Отметим, что наряду со строками в стиле С, которые, по сути, являются простыми массивами, есть также строковые литералы, такие как этот "literal" . В действительности, что строки, что литералы — это просто наборы символов, расположенных рядом в памяти компьютера. Но между массивами и литералами все таки есть разница, литералы нельзя изменять и строки — можно.

Любая функция, которая принимает строку в стиле С, также может принимать в качестве параметра — литерал. В си также есть некоторые сущности, которые могут выглядеть как строки, хотя, на самом деле, они таковыми не являются. Я сейчас говорю о символах, они заключены в одинарные кавычки, вот пример — "а" , как видите, это не строка. Символ можно, в определенном месте, присвоить строке, но символы не могут быть обработаны в виде строки. Если вы помните, массивы работают как указатели, поэтому, если вы передаете один символ в строку, это будет считаться ошибкой.

Из всего выше сказанного вы должны были понять, что строки — это массивы символов, а строковые литералы — слова, окруженные двойными кавычками. Вот еще один пример литерала:

"Это статическая строка"

Вы еще не забыли про специфику строк, которая упоминалась немного выше? Так вот, Си-строки всегда должны завершаться нулевым символом, буквально — "\0" . Поэтому, чтобы объявить строку, состоящую из 49 букв, необходимо зарезервировать дополнительную ячейку под нулевой символ:

Char myString;

Как видно из примера, длинна массива — 50 символов, 49 из которых займет строка и один, последний займет нулевой символ. Важно помнить, что в конце си-строк всегда должен быть нуль-символ, точно так же как и в конце каждого предложения есть точка. Хотя нуль символ не отображается при выводе строки, он все-равно занимает место в памяти. Поэтому, технически, в массиве из пятидесяти элементов вы смогли бы сохранить только 49 букв, потому что, последний символ нужен для завершения строки. Кроме того, указатели также могут быть использованы в качестве строки. Если вы читали статью про , вы можете сделать нечто подобное:

Char *myString; // указатель типа char myString = malloc(sizeof(*myString) * 64); // выделение памяти

В этом примере мы выделили 64 ячейки в памяти для массива myString . Для высвобождения памяти воспользуйтесь функцией free() .

Free(myString);

Использование строк

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

Когда считывает входные данные от пользователя, она будет читать все символы, кроме последнего. После этого в конец считанной строки, поместит нулевой терминатор. Функция fgets() будет cчитывать символы до тех пор, пока пользователь не нажмет Enter . Давайте посмотрим пример использования fgets() :

#include int main() { char myString; // длинная строка printf("Введите длинную строку: "); fgets(myString, 100, stdin); // считываем из потока ввода строку printf("Вы ввели следующую строку: %s", myString); getchar(); }

Первым параметром для fgets() является строка, второй параметр — размер строки и третий параметр — это указатель на входной поток данных.

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

<ВВОД>...

Как видите, из вывода программы, во входную строку попал символ новой строки — "\n" . Так случилось из-за того, что fgets() считала в строку myString нажатие кнопки Enter и завершила работу. Это означает, что вам может понадобиться вручную удалить символ новой строки. Один из способов сделать это, посимвольный перебор. Давайте доработаем программу и удалим символ новой строки:

#include int main() { char myString; // длинная строка printf("Введите длинную строку: "); fgets(myString, 100, stdin); // читываем из потока ввода строку int i; for (i = 0; i < 100; i++) { if (myString[i] == "\n") { myString[i] = "\0"; break; } } printf("Вы ввели следующую строку: %s", myString); getchar(); }

Обратите внимание, что если входная строка содержит меньше 100 символов, то в строку попадет и символ новой строки. Поэтому мы можем удалить этот символ, используя простой перебор. В программу мы добавили цикл, в котором перебираем символы строки, строки 12-19 . И когда нам встречается символ новой строки, мы его заменяем нулевым символом, строка 16 . Результат работы программы:

Введите длинную строку: Судьба оставляет свой отпечаток Вы ввели следующую строку: Судьба оставляет свой отпечаток Для закрытия данного окна нажмите <ВВОД>...

На этом пока все. В следующей статье я расскажу вам о специальных функциях для работы со строками.

P.S.: Все мы любим смотреть разные видео-записи, но иногда бывает так, что не всегда получается воспроизвести некоторые форматы видео-файлов. Так вот, решить эту проблему можно с помощью программы — xilisoft converter ultimate . Вы без труда сможете быстро переконвертировать видео из одного формата в другой. Кроме того, эта программа умеет конвертировать еще и аудио-файлы, и анимированные изображения.

Теги: string.h, обработка строк, строки в си

Библиотека string.h предоставляет функции для работы со строками (zero-terminated strings) в си, а также несколько функций для работы с массивами, которые сильно упрощают жизнь. Рассмотрим функции с примерами.

Копирование

void * memcpy (void * destination, const void * source, size_t num);

Копирует участок памяти из source в destination, размером num байт. Функция очень полезная, с помощью неё, например, можно скопировать объект или перенести участок массива, вместо поэлементного копирования. Функция производит бинарное копирование, тип данных не важен. Например, удалим элемент из массива и сдвинем остаток массива влево.

#include #include #include #define SIZE 10 int main() { int a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; unsigned index; int i; printf("Enter index "); scanf("%ud", &index); index = index < SIZE? index: SIZE-1; memcpy(&a, &a, sizeof(int) * (SIZE - index - 1)); for (i = 0; i < SIZE; i++) { printf("%d ", a[i]); } getch(); }

Функция меняет местами две переменные

#include #include #include #include void swap(void* a, void* b, size_t size) { void *tmp = malloc(size); memcpy(tmp, a, size); memcpy(a, b, size); memcpy(b, tmp, size); free(tmp); } int main() { float a = 300.456; float b = 0.645; swap(&a, &b, sizeof(float)); printf("a = %.3f\nb = %.3f", a, b); getch(); }

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

#include #include #include #include void swap(void* a, void* b, void* tmp, size_t size) { memcpy(tmp, a, size); memcpy(a, b, size); memcpy(b, tmp, size); } int main() { float a = 300.456; float b = 0.645; float tmp; swap(&a, &b, &tmp, sizeof(float)); printf("a = %.3f\nb = %.3f", a, b); getch(); } void* memmove (void * destination, const void * source, size_t num);

Копирует блок памяти из source в destination размером num байт с той разницей, что области могут пересекаться. Во время копирования используется промежуточный буфер, который предотвращает перекрытие областей.

#include #include #include void main () { char str = "memmove can be very useful......"; memmove (str + 20, str + 15, 11); puts(str); getch(); } char* strcpy (char * destination, const char* source);

Копирует одну строку в другую, вместе с нулевым символом. Также возвращает указатель на destination.

#include #include #include #include void main () { char buffer; char *word = NULL; scanf("%127s", buffer); word = (char*) malloc(strlen(buffer)+1); strcpy(word, buffer); printf("%s", word); free(word); getch(); }

Можно копировать и по-другому

#include #include #include #include void main () { char buffer; char *word = NULL; char *other = NULL; scanf("%127s", buffer); word = (char*) malloc(strlen(buffer)+1); other = strcpy(word, buffer); printf("%s", other); free(other); getch(); } char* strncpy (char* destination, const char* source, size_t num);

Копирует только num первых букв строки. 0 в конец не добавляется автоматически. При копировании из строки в эту же строку части не должны пересекаться (при пересечении используйте memmove)

#include #include #include #include void main () { char word = "Aloha, Hawaii"; char aloha; char hawaii; strncpy(aloha, word, 5); aloha = 0; strncpy(hawaii, &word, 7); printf("%s, %s", aloha, hawaii); getch(); }

Конкатенация строк

char* strcat (char * destination, const char * source);

Добавляет в конец destination строку source, при этом затирая первым символом нулевой. Возвращает указатель на destination.

Char* strncat (char * destination, const char * source, size_t num);

Добавляет в конец строки destination num символов второй строки. В конец добавляется нулевой символ.

#include #include #include void main () { char a; char b; scanf("%127s", a); scanf("%127s", b); strncat(a, b, strlen(b)/2); printf("%s", a); getch(); }

Сравнение строк

int strcmp (const char * str1, const char * str2);

Возвращает 0, если строки равны, больше нуля, если первая строка больше, меньше нуля, если первая строка меньше. Сравнение строк происходит посимвольно, сравниваются численные значения. Для сравнения строк на определённом языке используется strcoll

Int strcoll (const char * str1, const char * str2); int strncmp (const char * str1, const char * str2, size_t num);

сравнение строк по первым num символам
Пример - сортировка массива строк по первым трём символам

#include #include #include #include int cmp(const void *a, const void *b) { return strncmp((char*) a, (char*) b, 3); } void main() { char words = { "Solar", "Obscurus", "Tempestus", "Ultima", "Pacificus" }; int i; qsort(words, 5, 128, cmp); for (i = 0; i < 5; i++) { printf("%s\n", words[i]); } getch(); } size_t strxfrm (char * destination, const char * source, size_t num);

Трансформация строки в соответствии с локалью. В строку destination копируется num трансформированных символов строки source и возвращается её длина. Если num == 0 и destination == NULL, то возвращается просто длина строки.

#include #include #include #include void main() { char input; char output; scanf("%127s", input); //Выводи введённую строку printf("%s\n", input); //Проводим преобразование, ничего не меняется strxfrm(output, input, 128); printf("%s\n", output); //Изменяем локаль setlocale(LC_ALL, ".1251"); strxfrm(output, input, 128); printf("%s\n", output); getch(); }

Поиск

void* memchr (void * ptr, int value, size_t num);

Проводит поиск среди первых num байтов участка памяти, на который ссылается ptr, первого вхождения значения value, которое трактуется как unsigned char. Возвращает указатель на найденный элемент, либо NULL.

#include #include #include #include void main() { char str = "Hello World!"; char *ptr = NULL; ptr = (char*) memchr(str, "\0", 4000); if (ptr != NULL) { printf("first zero byte address is %p, strlen = %d", ptr, ptr - str); } else { printf("no null byte in memory block"); } getch(); } char* strchr (char * str, int character);

Возвращает указатель на место первого вхождения character в строку str. Очень похожа на функцию memchr, но работает со строками, а не с произвольным блоком памяти.

Size_t strcspn (const char * str1, const char * str2);

Возвращает адрес первого вхождения любой буквы из строки str2 в строке str1. Если ни одно включение не найдено, то возвратит длину строки.
Пример - найдём положение всех гласных в строке

#include #include #include void main() { char str = "So if you want to love me\n" "Then darling don"t refrain\n" "Or I"ll just end up walking\n" "In the cold November rain\n"; char vowels = "aeiouy"; int i; i = 0; while (str[i]) { i = i + strcspn(&str[i], vowels); printf("%d ", i); i++; } getch(); }

Здесь обратите внимание на строку i++ после printf. Если бы её не было, то strcspn возвращал бы всегда 0, потому что в начале строки стояла бы гласная, и произошло зацикливание.
Для решения этой задачи гораздо лучше подошла функция, которая возвращает указатель на первую гласную.

Char* strpbrk (char * str1, const char * str2)

Функция очень похожа на strcspn, только возвращает указатель на первый символ из строки str1, который есть в строке str2. Выведем все гласные в строке

#include #include #include void main() { char str = "Cos" it"s a bittersweet symphony this life...\n" "Trying to make ends meet, you"re a slave to the money then you die."; char vowels = "aeiouy"; char *p = NULL; p = strpbrk(str, vowels); while (p) { printf("%c ", *p); p++; p = strpbrk(p, vowels); } getch(); } char* strrchr (char * str, int character);

Возвращает указатель на последнее вхождение символа в троку.

Size_t strspn (const char * str1, const char * str2);

Возвращает длину куска строки str1, начиная от начала, который состоит только из букв строки str2.
Пример - вывести число, которое встречается в строке.

#include #include #include void main() { char str = "on 21st of May"; char nums = "0123456789"; char number; uintptr_t i; //Определяем, где начинаются цифры size_t start = strcspn(str, nums); //Определяем, где они заканчиваются, относительно start size_t end = strspn(&str, nums); for (i = 0; i < end; i++) { printf("%c", str); } getch(); } char* strstr (char * str1, const char * str2);

Возвращает указатель на первое вхождение строки str2 в строку str1.

#include #include #include void main() { char str = "I"ll drown my beliefs\n" "To have you be in peace\n" "I"ll dress like your niece\n" "And wash your swollen feet\n"; char niece = "niece"; char* p = strstr(str, niece); printf("%s", p); getch(); } char* strtok (char * str, const char * delimiters);

Разбивает строку на токены. В данном случае токенами считаются последовательности символов, разделённых символами, входящими в группу разделителей.

#include #include #include void main() { char str = "After working in India during the late 1970s and 1980s, " "Shankar"s profile in the West began to rise again in the mid-1990s " "as his music found its way into club DJ sets, particularly in London."; char delim = " \t\n\,.-"; char *p = strtok(str, delim); while (p != NULL) { printf ("%s\n",p); p = strtok (NULL, delim); } getch(); }

Ещё функции

void * memset (void * ptr, int value, size_t num); Заполняет блок памяти символами value числом num штук. Например, можно заполнить массив или структуру нулями. #include #include #include void main() { int arr; int i; memset(arr, 0, 10*10*sizeof(int)); for (i = 0; i < 10; i++) { arr[i][i] = 1; } for (i = 0; i < 10; i++) { int j; for (j = 0; j < 10; j++) { printf("%d", arr[i][j]); } printf("\n"); } getch(); }

Самая популярная функция

Size_t strlen (const char * str);

Возвращает длину строки - число символов от начала до первого вхождения нулевого.

Конверсия число-строка и строка-число.

int atoi (const char * str);

Переводит строку в целое

#include #include #include void main() { char ex1 = " 23 "; char ex2 = "rule43"; char ex3 = "21st of May"; printf("%d\n", atoi(ex1)); printf("%d\n", atoi(ex2)); printf("%d\n", atoi(ex3)); getch(); } double atof (const char* str);

Переводит строку в число типа double.

Long int atol (const char * str);

Переводит строку в число типа long
Все функции такого рода имеют название XtoY, где X и Y - сокращения типов. A обозначает ASCII. Соответственно, имеется обратная функция itoa (больше нет:)). Таких функций в библиотеке stdlib.h очень много, все их рассматривать не хватит места.

Форматированный ввод и вывод в буфер

Можно также выделить две функции sprintf и sscanf. Они отличаются от printf и scanf тем, что выводят данные и считывают их из буфера. Это, например, позволяет переводить строку в число и число в строку. Например

#include #include #include void main() { int i; float f; char buffer; scanf("%d", &i); scanf("%f", &f); sprintf(buffer, "%d", i); printf("%s\n", buffer); sprintf(buffer, "%.3f", f); printf("%s", buffer); getch(); }

Вообще, работа со строками - задача более глобальная, чем можно себе представить. Так или иначе, практически каждое приложение связано с обработкой текста.

Работа с локалью

char* setlocale (int category, const char* locale);

Устанавливает локаль для данного приложения. Если locale равно NULL, то setlocale может быть использована для получения текущей локали.

Локаль хранит информацию о языке и регионе, специфичную для работы функций ввода, вывода и трансформации строк. Во время работы приложения устанавливается локаль под названием "C", которая совпадает с настройками локали по умолчанию. Эта локаль содержит минимум информации, и работа программы максимально предсказуема. Локаль "C" также называется "". Константы category определяют, на что воздействует изменение локали.

Похожие публикации