Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Конец лекции


 

Пример 1:
/* сцепить строки */
#include <string.h>
void main(void)
{
char destination[25]=”This”;
char *blank = " ", *c = "C++";
strcat(destination, blank);
strcat(destination, c);
printf("%s\n", destination);
}

Пример 2:
#include <string.h>
void main(void)
{ char destination[25];
char *source = "structured ";
strcpy(destination,
"programming");
strncat(destination, source, 11);
}

 


Пример 3:
#include <string.h>
#include <stdio.h>
void main(void)
{ char *buf1 = "aaa", *buf2 = "bbb",;
int ptr;
ptr = strcmp(buf2, buf1);
if (ptr > 0)
printf("buf2 is greater than buf1\n");
else
printf("buf2 is less than buff1\n"); }

 



Пример 4:
int strncmp(char *str1, const char *str2, size_t n);

void main(void)
{ char *buf1 = "aaabbb",
*buf2 = "bbbccc";
int ptr;
ptr = strncmp(buf2,buf1,3);
if (ptr >0)
printf("buf2 is greater than buf1\n");
else
printf("buf2 is less than buf1\n");}


Пример 5:
void main(void)
{ char string[10];
char *str1 = "abcdefghi";
strcpy(string, str1);
printf("%s\n", string);}

 

Пример 6:
void main(void)
{ char string[10];
char *str1 = "abcdefghi";
strncpy(string, str1, 3);
string[3] = '\0';
printf("%s\n", string);}

 


Пример 7:
#include <stdio.h>
#include <string.h>
void main(void)
{ char *string = "Borland
International";
printf("%d\n", strlen(string));
}

 

Пример8:
void main(void)
{ char string[20];char *ptr,c = 'r';
strcpy(string,"This is a string");
ptr = strchr(string, c);
if (ptr)
printf("The character %c is at
position: %d\n", c, ptr);
else
printf("The character was not
found\n");}


Пример 9:
void main(void)
{char string[20];
char *ptr, c = 'r';
strcpy(string, "This is a string");
ptr = strrchr(string, c);

}

 

strpbrk - найти в строке str1 первое появление любого из множества символов, входящих в строку str2 (исключая завершающий знак NULL)
strpbrk возвращает yказатель на найденный в str1 символ или NULL-yказатель, если знаков из str2 в str1 нет. Пример 10:
char* strpbrk(const char *str1, const char *str2);
char str[80]="123 abc";
char *st1, *st2;
st1=strpbrk(str,"bca");
st2=strpbrk(str,”1bca");
//st1= abc
//st2 =123 abc

Пример 11:
#include <stdio.h>
#include <string.h>
void main(void) {
char *string1 = "abcdemnopqrstu";
char *string2 = "onm";
int *ptr;
ptr = strpbrk(string1, string2);
if (ptr)
printf(“found firstcharacter:%c\n",
ptr);
else
printf("didn't find character in set\n");}

strspn - определить длину подстроки (отрезка) строки str1, содержащего символы из множества, входящих в строку str2
size_t strspn(const char *str1, const char *str2);

Пример 12:
void main(void)
{char *string1 = "1234567890";
char *st1 = "123DC8", *st2="123D45C8";
char *st3 = "123DC584176";
int len1,len2, len3;
len1 = strspn(string1, st1);
len2 = strspn(string1, st2);
len3 = strspn(string1, st3); }
// len1=3 len2=5 len3=8

strcspn - определить длину начальной части отрезка строки str1, не содержащего символы cтроки str2
size_t strcspn(const char *str1, const char *str2);
Пример 13:
void main(void)
{ char *string1 = "1234567890";
char *string2 = "747DC8";
char *string3 = "7471DC8";

int len1,len2;
len1 = strcspn(string1, string2);
len2 = strcspn(string1, string3);
// len1=3 len2=0

strstr - Находит первое вхождение str2 в str1
char* strstr(const char *str1, const char *str2);
Находит первое вхождение str2 в str1 (без "\0"). В случае успеха возвращает указатель на найденную подстроку, в случае неудачи – 0.
Если str1 указывает на строку нулевой длины, то возвращает указатель на str1.

char str[80]=”123 abc 456”;
printf (”%s\n”,strstr(str,”abc”));
//печать: abc 456



Пример 14:
void main(void)
{ char input[16] = "abc,d,ef";
char *p;
p = strtok(input, ",");
if (p) printf("%s\n", p);
p = strtok(NULL, ",");
while(p!= NULL)
{printf(" %s\n", p);
// выбор следующего слова:
p = strtok(NULL, ”,”);
}
}

Функции для работы с памятью
void *memchr(const void *str, int c, size_t n);
Ищет первое вхождение с в n байтах str.

int memcmp(conct void *str1, const void *str2, size_t n);
Сравнивает первые n байт str1 и str2.

void *memcpy(void *str1, const void *str2,size_t n);
Копирует n байт из str2 в str1

void *memmove(void *str1, const void *str2,size_t n);
Копирует n байт из str2 в str1, перекрыв. строк

void *memset(void *str1, int c,size_t n);
Копирует c в n байт в str1.

Функции преобразования строки в числовые данные

Определены в <stdlib.h>

int atoi (const char *str);
long int atol (const char *str);
double atof(const char *str);

На вход они принимают указатель на строку, завершенную нулем, а возвращают - число, которое этой строкой описывается.
atoi и atol воспринимают следующий формат числа:
[ пробелы ][ знак ] цифры
atof, соответственно:
[ пробелы ][ знак ][ цифры ][. цифры ][{d | D | e | E }[ знак ] цифры ]


char str[]="12345";
int x,y;
double z;
x = atoi ("12345");
y = atol (str);
z = atof ("12.34");

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

Эту проблему решает следующий набор библиотечных функций, также включенных в стандартную библиотеку:
long strtol (const char* str,
char** end_ptr, int radix)
unsigned long strtoul
(const char* str,
char** end_ptr, int radix)
double strtod (const char* str, char** end_ptr)

{ int n; char *p;
n=strtol("12a",&p,0);
printf("n=%ld, stop %c\n",n,*p);
n=strtol("0x12",&p,0);
printf("n=%ld, stop %c\n",n,*p);
n=strtol("01117",&p,2);
printf("n=%ld, stop %c\n",n,*p);
return 1;}
//n=12 stop=a
//n=18
//n=7 stop=7

unsigned long int strtoul(...);
double strtod(const char *str, char ** endptr);

Замечание 1:
все функции перечисленные в этом параграфе, прекращают свою работу при встрече символа, который не подходит под параметры этого числа.
Замечание 2:
в случае если символ представлениия превосходит допустимый диапазон, то функции atof, strtol, strtoul, strtod устанавливают переменную errno в значение ERANGE(в <math.h>), при этом функции atof и strtod возвращают значение HUGE_VAL, функция strtol возвращает long_max или long_min, а функция strtoul возвращает long_max.

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

Нет специализированной функции (описанной в стандарте языка) для обратного преобразования (числа в строку). Но такие функции есть в RTL компиляторах.


Преобразование целого числа в строку

Для преобразования - следующими функциями:
char* _itoa(int value,
char* string, int radix);
char* _ltoa(long value,
char* string, int radix);
char* _ultoa(unsigned long
value,char* string, int
radix);

эти функции входят в библиотеку компиляторов от Microsoft.


Преобразование числа c плавающей точкой в строку
Для перевода чисел с плавающей точкой - функции:
char* _ecvt(double value, int count, int* dec, int* sign);
char* _fcvt (double value, int dcount, int* dec, int* sign);
char* _gcvt (double value, int digits, char* buffer);

- для Microsoft-компиляторов

Назначение функций следующее:
Функция ecvt конвертирует число (value) в заданное (count) количество символов, не выполняя при этом никакого форматирования.
Через параметр dec возвращается позиция, с которой начинается дробная часть (позиция десятичной точки), начиная с первого символа строки, а через параметр sign - признак того, что число имеет знак. Замечания:

1. Если строковое представление числа уже, чем необходимое количество символов, то число справа дополняется нулями.
2. Если строковое представление числа шире, чем необходимое количество символов, то возвращаемая через dec позиция находится правее завершающего строку нуля или левее первого символа строки. Выбор знака dec зависит от знака десятичной экспоненты числа. Например, для value= 3.5678e20 и count=6 функция вернет строку "356780", а dec будет равно 21. А для значения 3.5678e-20 и 6, будет возвращено, соответственно, "356780" и -19.
3. Преобразование производится во внутренний статический буфер, разделяемый с функцией fcvt, по этому необходимо быть осторожным при использовании функции в многопоточной среде.

Функция fcvt отличается от ecvt только тем, что параметр count задает не общее число символов, а число символов после десятичной точки (точность представление числа).
При этом строковое представление (по необходимости) дополняется справа нулями до получения нужной ширины.
Параметры dec и sign ведут себя аналогичным (как и для ecvt) образом. Для приведенных выше примеров возвращенные значения будут "356780000000000000000000000" и 21, а также "" и -19 соответственно.
В последнем случае возвращенная пустая строка означает, что строковое представление содержит только нули.

Функция gcvt преобразует заданное число (value) в строковое представление и помещает результат в переданный буфер (buffer).
При этом в буфер будет помещено не более digits цифр. Если число может быть представ-лено таким количеством цифр, то оно будет преобразовано в десятичный формат, иначе будет выполнено преобразование в экспоненци-альный формат, и заданное количество цифр будет содержать мантисса числа.
Строковое представление дополняется справа нулями для получения необходимого количества разрядов.

упражнение для КР (без компьютера)
int *x;
x=(int*)malloc(12);
*x=1;
x++;
*x=2;
x++;
*x=3;
printf("%d %d %d \n",x[-2],x[-1],x[0]);
printf("%d %d %d \n",x[0],x[1],x[2]);
printf("%d %d %d \n",*(x-2),*(x-1),*x);
printf("%d %d %d \n",*x--,*x--,*x--);
printf("%d %d %d \n",x[0],x[1],x[2]);

Нуль-терминированность поддерживается языком в следующих случаях:
при задании строковых констант. Так, строковая константа “Привет!” имеет длину 7 (что очевидно), но при описании
char *s = "Привет!";
будет создан массив из восьми элементов;
при вводе-выводе строк. Так, операторы ввода автоматически подставляют символ '\0' в конце строки, а операторы вывода выполняют поиск этого символа для определения конца строки;

при вызове стандартных функций работы со строками. Так, функция strlen(s) рассчитывает длину строки, исходя из поиска символа '\0'.
При формировании строки для совместимости со стандартными средствами языка должны правильно размещать признак конца строки. Так, результат вывода следующего фрагмента программы не определен:
char s[20];
s[0]=1;
cout << strlen(s) << endl;

Другой особенностью работы со строками является отсутствие каких-либо проверок на действительную длину строки. Так, написав
char *s;
cin >> s;

скорее всего, что-то куда-то введем. Ошибка может обнаружиться гораздо позднее, и совсем не там, где ее совершили…
Еще одна типичная ошибка в работе со строками связана с тем, что присваивание двух строковых переменных в Паскале и C трактуется по-разному. Для иллюстрации этого приведем фрагмент программы на Паскале и попытаемся дословно перевести ее в C.

В Паскале:
Var
S1, S2: string;

readln(S1);
S2:= S1;

// изменяем S1

S1:= S2;
// S1 восстановлена …

В С:
char *S1 = new char[255],
*S2 = new char[255];

cin >> S1;
S2 = S1; // а надо было strcpy(S2, S1);

// изменяем S1

S1=S2;
// увы, S1 не восстановлена …

/* Строки в качестве указателей */
void main()
{
printf("%s, %u, %c\n", "This ",
"character", *"string");
printf("%s", "This\n\tstring\n");
}
Вот что получится на экране:
This, 4281976, s
This
string

Почему?

Формат %s выводит строку "This ".

Формат %u выводит целое без знака, но так как строка "character", является указателем, то выдается его значение, являющееся адресом первого символа строки.

По формату %c выводится первый символ строки "string" (ибо *"string" -разыменованиеуказателя "string").

Указатели и строки
Большинство операций языка Си, имеющих дело со строками, работают с указателями. Рассмотрим бесполезную, но поучительную программу:
/* Указатели и строки */
void main()
{char *mesg = "Message";
char *copy;
copy = mesg;
printf("%s\n",copy);
printf("X = %s; значение = %u;
&X = %u\n",mesg,mesg,&mesg);
printf("X = %s; значение = %u;
&X = %u\n",copy,copy,&copy);}

Это не копирование строки.
На выходе получим:
Message
X = Message; значение = 4290432; &X = 1244960
X = Message; значение = 4290432; &X = 1244948
Третьим элементом в каждой строке является &X, т. е. адрес X.
Указатели mesg и copy записаны в ячейках 124948 и 124960, соответственно.
Второй элемент значение=. Это сам указатель. Значением указателя является адрес, который он содержит.
Оператор copy = mesg; создает второй указатель, ссылающийся на ту же самую строку. Сама строка не копируется.

printf("%d %d %d \n",x[-2],x[-1],x[0]);
1 2 3
printf("%d %d %d \n",x[0],x[1],x[2]);
3
-33686019 0
printf("%d %d %d \n",*(x-2),*(x-1),*x);
1 2 3
printf("%d %d %d \n",*x--,*x--,*x--);
3 3 3
printf("%d %d %d \n",x[0],x[1],x[2]);

33686019
1 2

<== предыдущая лекция | следующая лекция ==>
If (str3) | Будет выведено не значение east, а ее внутреннеее представление , т.е. число
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 440; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.031 сек.