Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Информатика_1 / C / lecture9 / lecture9

.html
Скачиваний:
11
Добавлен:
09.06.2015
Размер:
12.98 Кб
Скачать

Лекция 9. Работа со строками в языке Си. Table of Contents 1. Строки в языке Си. 2. Некоторые полезные функции для работы со строками. 3. Задачи. List of Figures1. Кодовая страница 866.2. Кодовая страница 1251.3. Кодовая страница KOI8-R.Строки в языке Си.   В языке Си нет специального типа данных для работы со строками. Строки хранятся в массиве элементов типа char или unsigned char. Вот два примера объявления строковых переменных char a[4]="for"; char * b="my string"; . В первой строке объявляется массив a , состоящий из четырех данных типа char. В памяти строки всегда хранятся с завершающим нулем, т.е. строка "for" занимает в памяти 4 байта - три байта на символы 'f','o' , 'r' и последний байт 0. Переменная b также является строкой под которую отведено в памяти 10 байтов - 9 байтов символы самой строки и последний байт со значением 0. Строки в программах на языке Си всегда представлены адресом первого элемента строки. Так переменнная a , как имя массива, является адресом первого элемента массива. Переменная b по объявлению также является адресом - адресом первого элемента строки "my string". Все функции, работающие со строками определяют конец строки по нулевому байту. Разница в объявлении строк a и b состоит в том , что b - переменная, которой можно присвоить значение. Например , можно написать b=a; . Но написать а=b; - нельзя , т.к. имя массива в языке Си всегда константа и ей нельзя присвоить значение. Под каждый символ строки в памяти отводится один байт (UNICODE символы рассматриваются в 11-ой лекции), в котором пишется номер ASCII кода символа. Все символы, которые можно отобразить на экране пронумерованы от нуля до 255 (максимальное число, которое можно записать в один байт) . Этот набор символов и называют обычно ASCII (от american standart information interchange). Если быть совсем точным ,то под ASCII символами понимают первые 128 символов . Вторые 128 символов обычно отводятся под национальный алфавит. Так появляются на свет кодовые страницы. Например, существует несколько кодовых страниц для хранения русского алфавита, которые отличаются друг от друга лишь номерами позиций в которых занесен русский алфавит. Приведу для примера три набора таблиц символов, соответствующих кодовым страницам 866 ( кодовая страница , применявшаяся в операционной системе DOS и применяющаяся по сей день в консоли операционных систем Windows) , 1251 - кодовая страница, которая была введена в операционной системе Windows, KOI8-R - кодовая таблица применяющаяся для хранения русского алфавита в операционных системах UNIX. Figure 1. Кодовая страница 866. Figure 2. Кодовая страница 1251. Figure 3. Кодовая страница KOI8-R. Как я уже отмечал каждый символ строки занимает в памяти компьютера один байт, где записан номер его кода в кодовой таблице. Сами изображения символов хранятся в специальных файлах , которые называются файлами шрифтов. Обсуждение содержимого этих файлов выходит за рамки этих лекций. Отмечу лишь , что показаннные выше начертания символов ,соответствующих различным кодовым страницам были выведены на экран с использованием стандартного консольного шрифта Windows. А вот пример небольшой программы ,позволяющей посмотреть на экране содержимое всех десяти байтов строки b , приведеннной в качестве примера в начале лекции. Эта программа выводит на экран , как номера всех ASCII символов этой строки , так и их начертания. (файл l9_1.c) /*1*/ #include <stdio.h> /*2*/ void main(void){ /*3*/ char *b="my string"; /*4*/ int i; /*5*/ for(i=0;i<10;i++)printf("ascii=%d character=%c\n",b[i],b[i]); /*6*/ } В пятой строке этой программы на экран выводится i-ый элемент строки b сначала по формату для вывода целых чисел (%d), а затем по формату для вывода символов (%c). Кроме того из этой строки можно видеть , что к элементам строки можно обращаться, как к элементам массива. Вот результат работы этой программы на экране ascii=109 character=m ascii=121 character=y ascii=32 character= ascii=115 character=s ascii=116 character=t ascii=114 character=r ascii=105 character=i ascii=110 character=n ascii=103 character=g ascii=0 character= Press any key to continue . Иногда бывает необходимо добавить в строку специальные символы , такие как \, ", ' . Для добавления таких символов в строку они должны быть указаны после обратной косой. Например, чтобы вставить обратную косую в строку ее нужно указать дважды . Иногда бывает необходимо при связывании указателя на поток с файлом с помощью функции fopen указать полный путь к файлу. Вот как , например , это можно сделать str=fopen("e:\\ivanov\\integrals\\res.dat","w+"); . Иногда бывает необходимо вставить в строку символ , которого нет на клавиатуре. Это делается также с помощью ESC - последовательности - нужно после обратной косой указать номер вставляемого ASCII символа. Но номер указывается либо в восьмеричной системе счисления , либо в шестнадцатеричной. Для записи чисел в восьмеричной системе счисления используются символы 0,1,2,3,4,5,6,7. Например, если Вы вставили в строку символы \273 это означает , что в строку вставлен ASCII символ с десятичным номером 3*(8^0)+7*(8^1)+2*(8^2)=187. Для записи чисел в шестнадцатеричной системе счисления используются символы 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f. Заглавные и строчные буквы при записи шестнадцатеричных чисел равноправны. Символ a используется для обозначения десятичного числа 10, символ b - 11, c -12, d- 13, e- 14, f -15. Для записи шестнадцатеричных чисел в программах на языке Си перед ними ставится символ x. Так , например, если Вы вставили в строку символы \x3c , то это обозначает , что Вы вставили в строку ASCII символ с десятичным номером c*(16^0)+3*(16^1)=12*1+3*(16^1)=60. Некоторые полезные функции для работы со строками. . В этом параграфе приводятся некоторые полезные функции для работы со строками. Заголовки всех функций для работы со строками содержатся в заголовочном файле string.h. Получить число символов в строке позволяет функция size_t strlen(const char * str). Эта функция в качестве входного параметра получает указатель на строку str и возвращает число символов в строке. Завершающий строку нулевой байт в это число не включается. Сшить вместе две строки позволяет функция char * strcat(const char *s1,const char *s2); . Эта функция к строке s1 присоединяет строку s2. Необходимо позаботиться , чтобы в строке s1 было достаточно памяти для прибавления всех элементов строки s2. Функция возвращает указатель на результирующую строку. Найти заданную строку в другой строке позволяет функция char * strstr(const char *s1, const char * s2); . Эта функция ищет строку s2 в строке s1. Если строка найдена , функция возвращает адрес первого элемента строки s2 в строке s1. Следует иметь в виду, что функция strstr определяет лишь первое вхождение строки s2 в строку s1, все остальные включения игнорируются . Скопировать одну строку в другую позволяет функция char *strcpy( char *strDestination, const char *strSource ); . Эта функция копирует строку strSource вместе с завершающим нулем в строку strDestination. Переполнение не проверяется. Использовать функции scanf и fscanf для чтения строк с консоли и из файлов не рекомендуется , поскольку эти функции читают входной поток до первого пробельного символа и не позволяют вводить строки, состоящие из нескольких слов. Для ввода строк с консоли обычно используют функцию gets, объявленную в заголовочном файле stdio.h char *gets( char *buffer );. Эта функция читает строку с консоли до нажатия клавиши ENTER и помещает считанную строку в память , начиная с адреса buffer. В случае успешного завершения gets возвращает указатель на первый символ , считанной строки (buffer). В случае неудачного завершения возвращается NULL (макрос , определенный в stdio.h). Для считывания строк из файла пименяется функция fgets, объявленная в заголовочном файле stdio.h char *fgets( char *string, int n, FILE *stream );. Эта функция читает строку из потока stream до символов CRLF (13 10). Прочитанные символы заносятся в строку string вместе с символами CR(13) и LF(10). Последним символом в string помещается \0. В строку помещается не более n символов. Если входная строка содержит больше, чем n символов , она урезается и последним символом в string все равно будет \0. При использовании функций gets и fgets Вы должны позаботиться о достаточном количестве памяти, выделенной под считываемые строки в переменных buffer и string. Для записи строк в файл используется функция fputs, объявленная в заголовочном файле stdio.h int fputs( const char *string, FILE *stream );. Эта функция пишет строку string в поток stream. Если символов CR(13) и LF(10) в строке string не было, то они в поток не посылаются. Вы должны сами включать символы CR и LF в строку string, посылаемую в поток stream. Функции для работы с Unicode строками, а также функции, производящие преобразование различных типов данных в строки и обратно рассматриваются в лекции 11. Далее приводятся два примера программ для работы со строками. В первом примере из файла in_out.c считывается строка, затем в в ней ищется подстрока "for" и если такая подстрока найдена, то строка пишется в файл out. (файл l9_2.c) /*1*/ #include<stdio.h> /*2*/ #include<string.h> /*3*/ void main(void){ /*4*/ char *s="for",a[255],*b; /*5*/ FILE *str,*str1; /*6*/ str=fopen("in_out.c","rb"); /*7*/ str1=fopen("out","wb"); /*8*/ while(!feof(str)){fgets(a,255,str); /*9*/ if((b=strstr(a,s))!=NULL) {printf("%s\n",b); fprintf(str1,"%s",a); } /*10*/ } /*11*/ fclose(str1); /*12*/ fclose(str); /*13*/ } В следующем примере в файле text.txt ищутся строки , содержащие строку "for", затем эта строка заменяется на строку "while" и результат пишется в файл text1.txt. (файл l9_3.c) /*1*/ #include<stdio.h> /*2*/ #include<string.h> /*3*/ #include<stdlib.h> /*4*/ void main(void){ /*5*/ char *s="for",*s1="while",a[255],*b,temp[255]; /*6*/ long l,i; /*7*/ FILE *str,*str1; /*8*/ if(!(str=fopen("text.txt","rb"))){perror("error opening text.txt\n"); /*9*/ exit(1); /*10*/ } /*11*/ str1=fopen("text1.txt","wb"); /*12*/ while(!feof(str)){ /*13*/ fgets(a,255,str); /*14*/ b=strstr(a,s); /*15*/ if(b!=NULL) { /*16*/ l=b-a; /*17*/ for(i=0;i<l;i++)temp[i]=a[i]; /*18*/ temp[l]=0; /*19*/ strcat(temp,s1); /*20*/ strcat(temp,b+strlen(s)); /*21*/ fputs(temp,str1); /*22*/ } /*23*/ } /*24*/ /*25*/ fclose(str1); /*26*/ fclose(str); /*27*/ } В этой программе , считываемая из файла text.txt строка помещается в переменную a , а новая строка, в которой "for" замененo на "while" , собирается в переменной temp и затем эта строка (temp) пишется в файл text1.txt. Задача. Переписать программу из файла l9_3.c так, чтобы заменялись все вхождения строки "for" в считанной строке , а не только первые. previous next home

Соседние файлы в папке lecture9