
Конкатенация (объединение) строк
Сначала простой вопрос – каков результат выполнения следующего кода:
char str1[10]="Hello"; char str2[10]="World!"; char* str3; str3=str1+str2; |
Если ответ – ошибка на этапе компиляции, материал изложенный в статье вы усвоили (или знали это раньше). Если же вы полагаете, что в str3 будет хранится строка "Hello world!", то вероятно, мои предыдущих объяснений оказалось недостаточно. Нельзя складывать указатели (и имена массивов).
Для конкатенации следует использовать функции.
Есть две специальные функции:
char* strcat(char* dest, const char* source) char* strncat(char* dest, const char* source, size_t size) |
Эти функции добавляют к строке, на которую указывает dest, символы из строки source. Первая версия добавляет все символы до нуль-символа, вторая – максимум size символов. Результирующая строка завершается нуль-символом.
Поиск одного из символов одной строки в другой
Char *strcspn(char *s1, char *s2); Возвращает значение индекса любого из символов из s2 в строке s1.
Поиск символа одной строки, отсутствующий в другой
Char *strspn(char *s1, char *s2); Возвращает индекс первого символа в s1, отсутствующего в s2.
char *string1 = "14234567890";
char *string2 = "123DC8";
int length;
length = strspn(string1, string2);
printf("Character where strings differ is at position %d\n", length);//1
strpbrk - найти в строке s1 любой из множества символов, входящих в строку s2.
char *strpbrk(char *s1,char *s2);
char *string1 = "abcdefghijklmnopqrstuvwxyz";
char *string2 = "onm";
char *ptr;
ptr = strpbrk(string1, string2);
if (ptr)
printf("strpbrk found first character: %d\n", ptr-string1);
else
printf("strpbrk didn't find character in set\n");
strtok - выделить из строки s1 лексемы, разделенные любым из множества символов, входящих в строку s2.
char *strtok(char *s1,char *s2);
char *s1, *s2;
char input[16] = "a;b c,d";
char *p;
p = strtok(input, ", ;");
while(p){
printf("%s\n", p);
p = strtok(NULL, ", ;");
}
Первый вызов формирует адрес первой лексемы в строке input. Он сохраняется в переменной р. Функция strtok заменяет на NULL разделитель находящийся после найденного слова. Оператор strtok в цикле выполняет поиск следующей лексемы в той же строке. Для этог следует задать в функции strtok в качестве первого параметра NULL.
Использование функций strupr и strlwr библиотеки этапа выполнения:
cout << "Верхний регистр: " << strupr(title) << endl; cout << "Нижний регистр: " << strlwr(lesson) << endl;
ПРЕДУПРЕЖДЕНИЕ
Не путайте ‘\0’, ‘0’ и “0”. Первое – символьный литерал, соответствующий символу с кодом 0. Второе – такой же литерал, но обозначающий цифру 0, ее код в ASCII-кодировке 48. Третий — это строковый литерал, содержащий два символа, цифру 0 и нуль-терминатор.
Если в строке нет символа "+", то оставить строку без изменения, иначе каждую цифру , предществующую первому вхождению знака "+" заменить на "*"
#include "iostream"
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
using namespace std;
void main()
{ char s1[30],s2[20],s3[20],*ptr;
int i;
cout<<"\nVvedite s1 ";gets(s1);
ptr=strchr(s1,'+');
if (ptr) {cout<<"position="<<ptr-s1;
for(i=0;i<ptr-s1;i++)
{if (isdigit(s1[i]))s1[i]='*';}
}
else cout<<" null ";
cout<<s1;
return;
}
вывести все слова строки в алфавином порядке
#include "iostream"
using namespace std;
void main()
{ char str[100],*ptr;
char mat[10][100];
cout<<"vvedite stroky"<<endl;
gets(str);
cout<<"dlina stroki "<<strlen(str)<<endl;
int i=0;
ptr=strchr(str,' ');
while(ptr)
{ strncpy(mat[i],str,ptr-str);
mat[i][ptr-str]='\0';
cout<<i<<"-slovo="<<mat[i]<<endl;
i++;
strcpy(str,ptr+1);
cout<<"*****"<<str<<endl;
cout<<"dlina stroki "<<strlen(str)<<endl;
ptr=strchr(str,' ');
}
strcpy(mat[i],str);
mat[i][strlen(str)]='\0';
cout<<i<<"-slovo="<<mat[i]<<endl;
//сортировка
int n=i;
for(i=n-1;i>0;i--)
for(int j=0;j<=i;j++)
{if(strcmp(mat[j],mat[j+1])>0)
{strcpy(str,mat[j]);
strcpy(mat[j],mat[j+1]);
strcpy(mat[j+1],str);
}
}
for(i=0;i<n;i++)
{cout<<mat[i]<<endl;
}
return ;
}
Функции ввода/вывода
Ввод/вывод в С++ реализуется либо с помощью функций, унаследованных от библиотек С, либо с помощью потоков С++. Смешивать эти два способа в одной программе не рекомендуется.
Для использования функций ввода/вывода в стиле С необходимо подключить к программе заголовочный файл <stdio.h> или <cstdio>. При вводе/выводе данные рассматриваются как поток байтов. Физически поток представляет собой файл или устройство, например, клавиатуру или дисплей, рассматривающиеся как частный случай файла.
Открытие потока
1. Файл открывается. Это означает, что программа "захватывает" заданный по имени файл, сообщает Windows, что далее она будет с ним работать. Данный шаг нужен, чтобы не возникало конфликтов, когда несколько программ одновременно хотят записывать информацию в один и тот же файл. Правда, считывать данные из файла, очевидно, допустимо одновременно множеством программ, поэтому в операции открытия файла обычно уточняется, что файл открывается "на чтение" (считывание информации, которая не меняется) либо "на запись" (данные в файле модифицируются). Операция открытия файла возвращает некий идентификатор (как правило, целое число), которое идентифицирует в программе в дальнейшем нужный открытый файл. Этот идентификатор запоминается в переменной; обычно такая переменная называется файловой переменной.
2. Ведется работа с файлом. Из него данные либо считываются, либо в него записываются.
3. Файл закрывается. После этой операции он снова доступен другим программам для обработки.
Работа с потоком начинается с его открытия. Поток можно открыть для чтения и/или записи в двоичном или текстовом режиме. Функция открытия потока имеет формат:
FILE* fopen(const char* filename, const char* mode);
При успешном открытии потока функция возвращает указатель на предопределенную структуру типа FILE, содержащую всю необходимую для работы с потоком информацию, или NULL в противном случае. Первый параметр - имя открываемого файла в виде С-строки, второй - режим открытия файла:
"r" - файл открывается для чтения;
"w" - открывается пустой файл для записи (если файл существует, он стирается);
"a" - файл открывается для добавления информации в его конец;
"r+" - файл открывается для чтения и записи (файл должен существовать);
"w+" - открывается пустой файл для чтения и записи (если файл существует, он стирается);
Режим открытия может также содержать символы t (текстовый режим) или b (двоичный режим), отличающиеся обработкой символов перехода на новую строку. По умолчанию файл открывается в текстовом режиме, при котором комбинация символов "возврат каретки" и "перевод строки" (0x13 0x10) при вводе преобразуются в одиночный символ перевода строки (при выводе выполняется обратное преобразование). В двоичном режиме преобразования не выполняются.
Пример:
FILE *f = fopen("d:\\cpp\\data.txt", "rb+");
Тогда команда открытия (создания пустого) файла запишется так:
FILE * fo; fo = fopen("test.txt","wt");
Можно задать и полный путь к файлу, например:
fo = fopen("c:\\tmp\\test.txt","wt");
Не забываем, что одиночный символ \ внутри строки Си задается двумя наклонными слэшами \\. Это частая ошибка.
После открытия файла в файловую переменную fo занесется некоторое число. Если таким числом будет ноль, считается, что файл открыть не удалось. В Си нередки записи вида
if( (fo=fopen("c:\\tmp\\test.txt","wt")) == 0 ) { // ошибка! }
где одновременно открывается файл и проверяется, успешно ли это сделано.
Указатель fo используется в дальнейших операциях с потоком. Его передают функциям ввода/вывода в качестве параметра.
При открытии потока с ним связывается область памяти, называемая буфером. При выводе вся информация направляется в буфер и накапливается там до заполнения буфера или до закрытия потока. Чтение осуществляется блоками, равными размеру буфера, и данные читаются из буфера.
Существует пять предопределенных потоков, которые открываются в начале работы программы: стандартный ввод stdin, стандартный вывод stdout, стандартный вывод сообщений об ошибках stderr, стандартный дополнительный поток stdaux и стандартная печать stdprn.
Ввод/вывод в поток
Ввод/вывод в поток можно осуществлять различными способами: в виде последовательности байтов, в виде символов и строк или с использованием форматных преобразований. Для каждого вида операций определен свой набор функций.
Операции ввода/вывода выполняются начиная с текущей позиции потока, определяемой положением указателя потока. Указатель устанавливается при открытии на начало или конец файла (в соответствии с режимом открытия) и изменяется автоматически после каждой операции ввода/вывода.
Ниже перечислены основные функции ввода/вывода потока.
Чтение и запись потока байтов выполняют функции fread и fwrite.
Чтение символа из потока - getc, fgetc, из стандартного потока stdin - getchar.
Запись символа в поток - putc, fputc, в стандартный поток stdout - putchar.
Чтение строки из потока - fgets, из стандартного потока stdin - gets.
Запись строки в поток - fputs, в стандартный поток stdout - puts.
Форматированный ввод из потока - fscanf, из стандартного потока stdin - scanf, из строки - sscanf.
Форматированный вывод в поток - fprintf, в стандартный поток stdout - printf, в строку - sprintf.
Закрытие потока
Поток закрывается либо при завершении программы, либо явным образом с помощью функции fclose:
int fclose(FILE*);
Перед закрытием потока информация из связанных с ним буферов выгружается на диск. Рекомендуется явным образом закрывать потоки, открытые для записи.