sonyps4.ru

Работа со строками в си примеры. Ввод и вывод символьных строк в си

Теги: Си строки. 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(); }

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

Работа со строками. Класс string . Конструкторы класса. Функции assign() , append() , insert() , replace() , erase() , find() , rfind() , compare() , c_str() . Примеры

1. Какое назначение класса string в программах на C++?

Класс string предназначен для работы со строками типа char* , которые представляют собой строку с завершающим нулем. Класс string был введенн как альтернативный вариант для работы со строками типа char* . Строки, которые завершаются символом ‘\0’ еще называются C-строками. Поскольку, string есть классом, то можно объявлять объекты этого класса.

2. Какие модули (библиотеки) нужно подключить, чтобы использовать возможности класса string в MS Visual Studio C++?

Чтобы использовать возможности класса string в MS Visual Studio (C++), нужно подключить библиотеку и пространство имен std .

#include using namespace std;
3. Каким образом осуществляется объявление переменной типа string ? Примеры

Объявление переменной типа string осуществляется точно так же как и обычной переменной. Возможный вариант объявления с одновременной инициализацией.

// тип string string s1; // переменная с именем s1 типа string string s2 = "This is a string variable" ; // объявление с инициализацией // использование переменной типа string с оператором присваивания s1 = s2; // s1 = "This is a string variable" s2 = "New text" ;
4. Какие преимущества и недостатки дает использование класса string в сравнении с типом char* ?

Создание нового типа string было обусловлено недостатками работы с строками символов, который демонстрировал тип char* . В сравнении с типом char* тип string имеет следующие основные преимущества:

  • возможность обработки строк стандартными операторами C++ (= , + , = = , <> и т.п.). Как известно, при использовании типа char* даже наиболее простые операции со строками выглядели сложно и требовали написания чрезмерного программного кода;
  • обеспечение лучшей надежности (безопасности) программного кода. Например, при копировании строк, тип string обеспечивает соответствующие действия, которые могут возникнуть в случае, если строка-источник имеет больший размер чем строка-приемник;
  • обеспечение строки, как самостоятельного типа данных. Объявление типа string как строки есть единым для всех переменных в программе, которая обеспечивает непротиворечивость данных.

Основным недостатком типа string в сравнении с типом char* , есть замедленная скорость обработки данных. Это связано с тем, что тип string – это, фактически, контейнерный класс. А работа с классом требует дополнительной реализации программного кода, который, в свою очередь занимает лишнее время.

5. Какие операторы можно использовать с объектами класса string ?

Класс string есть удобен тем, что позволяет удобно манипулировать строками, используя стандартные (перегруженные) операторы.

С объектами класса string можно использовать нижеследующие операторы

  • = – присваивание
  • + – конкатенация (объединение строк)
  • += – присваивание с конкатенацией
  • == – равенство
  • != – неравенство
  • < – меньше
  • <= – меньше или равно
  • > – больше
  • >= – больше или равно
  • – индексация

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

// тип string, операции над строками string s1 = "s-1" ; string s2 = "s-2" ; string s3; bool b; // операция "=" (присваивание строк) s3 = s1; // s3 = "s-1" // операция "+" - конкатенация строк s3 = s3 + s2; // s3 = "s-1s-2" // операция "+=" - присваивание с конкатенацией s3 = "s-3" ; s3 += "abc" ; // s3 = "s-3abc" // операция "==" - сравнение строк b = s2==s1; // b = false b = s2=="s-2" ; // b = true // операция "!=" - сравнение строк (не равно) s1 = "s1" ; s2 = "s2" ; b = s1 != s2; // b = true // операции "<" и ">" - сравнение строк s1 = "abcd" ; s2 = "de "; b = s1 > s2; // b = false b = s1 < s2; // b = true // операции "<=" и ">=" - сравнение строк (меньше или равно, больше или равно) s1 = "abcd" ; s2 = "ab" ; b = s1 >= s2; // b = true b = s1 <= s2; // b = false b = s2 >= "ab" ; // b = true // операция - индексация char c; s1 = "abcd" ; c = s1; // c = "c" c = s1; // c = "a"
6. Содержит ли класс string конструкторы?

Как и любой класс, класс string имеет ряд конструкторов. Основные из них следующие:

String(); string(const char * str); string(const string & str);

7. Примеры инициализации с помощью конструкторов

Ниже приведены примеры инициализации переменных типа string

String s1("Hello!" ); string s2 = "Hello!" ; // инициализация - конструктор string(const char * str) char * ps = "Hello" ; string s3(ps); // инициализация string s4(s3); // инициализация - конструктор string(const string & str) string s5; // инициализация - конструктор string()

8. Присваивание строк. Функция assign() . Примеры

Чтобы присвоить одну строку другой, можно применить один из двух методов:

  • использовать оператор присваивания ‘=’ ;
  • использовать функцию assign() из класса string .

Функция assign() имеет несколько перегруженных реализаций.

Первый вариант – это вызов функции без параметров

String &assign(void );

В этом случае происходит простое присваивание одной строки другой.

Второй вариант позволяет копировать заданное количество символов из строки:

String &assign(const string & s, size_type st, size_type num);

  • s – объект, из которого берется исходная строка;
  • st – индекс (позиция) в строке, из которой начинается копирование num символов;
  • num – количество символов, которые нужно скопировать из позиции st ;
  • size_type – порядковый тип данных.

Третий вариант функции assign() копирует в вызывающий объект первые num символов строки s :

String & assign(const char * s, size_type num);

  • s – строка, которая завершается символом ‘\0’ ;
  • num – количество символов, которые копируются в вызывающий объект. Копируются первые num символов из строки s .

Ниже приведен пример с разными реализациями функции assign() .

Пример.

// присваивание строк, функция assign() string s1 = "сайт" ; string s2; string s3; char * ps = "сайт" ; s3 = s1; // s3 = "сайт" s2.assign(s1); // s2 = "сайт" s2.assign(s1, 0, 4); // s2 = "best" s2.assign(ps, 8); // s2 = "bestprog"
9. Объединение строк. Функция append() . Пример

Для объединения строк используется функция append() . Для добавления строк также можно использовать операцию ‘+’ , например:

String s1; string s2; s1 = "abc" ; s2 = "def" ; s1 = s1 + s2; // s1 = "abcdef"

Однако, функция append() хорошо подходит, если нужно добавлять часть строки.

Функция имеет следующие варианты реализации:

String &append(const string & s, size_type start); string &append(const char * s, size_type num);

В первом варианте реализации функция получает ссылку на строчный объект s , который добавляется к вызывающему объекту. Во втором варианте реализации функция получает указатель на строку типа const char * , которая завершается символом ‘\0’ .

Пример. Демонстрация работы функции append() .

String s1 = "abcdef" ; s2 = "1234567890" ; append(s2, 3, 4); // s1 = "abcdef4567" char * ps = "1234567890" ; s1 = "abcdef" ; s1.append(ps, 3); // s1 = "abcdef123"

10. Вставка символов в строке. Функция insert() . Пример

Чтобы вставить одну строку в заданную позицию другой строки нужно использовать функцию insert() , которая имеет несколько вариантов реализации.

Первый вариант функции позволяет вставить полностью всю строку s в заданную позицию start вызывающей строки (вызывающего объекта):

String & insert(size_type start, const string &s);

Второй вариант функции позволяет вставить часть (параметры insStart , num ) строки s в заданную позицию start вызывающей строки:

String & insert(size_type start, const string &s, size_type insStart, size_type num);

В вышеприведенных функциях:

  • s – строка, которая вставляется в вызывающую строку;
  • start – позиция в вызывающей строке, из которой осуществляется вставка строки s ;
  • insStart – позиция в строке s , из которой происходит вставка;
  • num – количество символов в строке s , которые вставляются с позиции insStart .
string s1 = "abcdef" ; string s2 = "1234567890" ; s1.insert(3, s2); // s1 = "abc"+"1234567890"+"def"="abc1234567890def" s2.insert(2, s1, 1, 3); // s2 = "12bcd34567890"
11. Замена символов в строке. Функция replace() . Пример

Функция replace() выполняет замену символов в вызывающей строке. Функция имеет следующие варианты реализации:

String &replace(size_type start, size_type num, const string &s); string &replace(size_type start, size_type num, const string &s, size_type replStart, size_type replNum);

В первом варианте реализации вызывающая строка заменяется строкой s . Есть возможность задать позицию (start ) и количество символов (num ) в вызывающей строке, которые нужно заменить строкой s .

Второй вариант функции replace() отличается от первого тем, что позволяет заменять вызывающую строку только частью строки s . В этом случае задаются два дополнительных параметра: позиция replStart и количество символов в строке s , которые образуют подстроку, которая заменяет вызывающую строку.

Пример. Демонстрация работы функции replace() .

String s1 = "abcdef" ; string s2 = "1234567890" ; s2.replace(2, 4, s1); // s2 = "12abcdef7890" s2 = "1234567890" ; s2.replace(3, 2, s1); // s2 = "123abcdef67890" s2 = "1234567890" ; s2.replace(5, 1, s1); // s2 = "12345abcdef7890" // замена символов, функция replace() string s1 = "abcdef" ; string s2 = "1234567890" ; s2.replace(2, 4, s1); // s2 = "12abcdef7890" s2 = "1234567890" ; s2.replace(3, 2, s1); // s2 = "123abcdef67890" s2 = "1234567890" ; s2.replace(5, 1, s1); // s2 = "12345abcdef7890" s2 = "1234567890" ; s2.replace(5, 1, s1, 2, 3); // s2 = "12345cde7890" s2 = "1234567890" ; s2.replace(4, 2, s1, 0, 4); // s2 = "1234abcd7890"

12. Удаление заданного количества символов из строки. Функция erase() . Пример

Для удаления символов из вызывающей строки используется функция erase() :

String & erase(size_type index=0, size_type num = npos);

  • index – индекс (позиция), начиная из которой нужно удалить символы в вызывающей строке;
  • num – количество символов, которые удаляются.

Пример.

String s = "01234567890" ; s.erase(3, 5); // s = "012890" s = "01234567890" ; s.erase(); // s = ""

13. Поиск символа в строке. Функции find() и rfind() . Примеры

В классе string поиск строки в подстроке можно делать двумя способами, которые отличаются направлением поиска:

  • путем просмотра строки от начала до конца с помощью функции find() ;
  • путем просмотра строки от конца к началу функцией rfind() .

Прототип функции find() имеет вид:

Size_type find(const string &s, size_type start = 0) const ;

  • s – подстрока, которая ищется в строке, что вызывает данную функцию. Функция осуществляет поиск первого вхождения строки s . Если подстрока s найдена в строке, что вызвала данную функцию, тогда возвращается позиция первого вхождения. В противном случае возвращается -1;

Прототип функции rfind() имеет вид:

Size_type rfind(const string &s, size_type start = npos) const ;

  • s – подстрока, которая ищется в вызывающей строке. Поиск подстроки в строке осуществляется от конца к началу. Если подстрока s найдена в вызывающей строке, то функция возвращает позицию первого вхождения. В противном случае функция возвращает -1;
  • npos – позиция последнего символа вызывающей строки;
  • start – позиция, из которой осуществляется поиск.

Пример 1. Фрагмент кода, который демонстрирует результат работы функции find()

// тип string, функция find() string s1 = "01234567890" ; string s2 = "345" ; string s3 = "abcd" ; int pos; pos = s1.find(s2); // pos = 3 pos = s1.find(s2, 1); // pos = 3 pos = s1.find("jklmn" , 0); // pos = -1 pos = s1.find(s3); // pos = -1 pos = s2.find(s1); // pos = -1

Пример 2. Демонстрация работы функции rfind() .

// тип string, функции find() и rfind() string s1 = "01234567890" ; string s2 = "345" ; string s3 = "abcd" ; string s4 = "abcd---abcd" ; int pos; pos = s1.rfind(s2); // pos = 3 pos = s1.rfind(s2, 12); // pos = 3 pos = s1.rfind(s2, 3); // pos = 3 pos = s1.rfind(s2, 2); // pos = -1 pos = s2.rfind(s1); // pos = -1 pos = s1.rfind(s3, 0); // pos = -1 // разница между функциями find() и rfind() pos = s4.rfind(s3); // pos = 7 pos = s4.find(s3); // pos = 0
14. Сравнение частей строк. Функция compare() . Пример

Поскольку тип string есть классом, то, чтобы сравнить две строки между собой можно использовать операцию ‘= =’ . Если две строки одинаковы, то результат сравнения будет true . В противном случае, результат сравнения будет false .

Но если нужно сравнить часть одной строки с другой, то для этого предусмотрена функция compare() .

Прототип функции compare() :

int compare(size_type start, size_type num, const string &s) const ;
  • s – строка, которая сравнивается с вызывающей строкой;
  • start – позиция (индекс) в строке s , из которой начинается просмотр символов строки для сравнения;
  • num – количество символов в строке s , которые сравниваются с вызывающей строкой.

Функция работает следующим образом. Если вызывающая строка меньше строки s , то функция возвращает -1 (отрицательное значение). Если вызывающая строка больше строки s , функция возвращает 1 (положительное значение). Если две строки равны, функция возвращает 0.

Пример . Демонстрация работы функции compare() :

// тип string, функция compare() string s1 = "012345" ; string s2 = "0123456789" ; int res; res = s1.compare(s2); // res = -1 res = s1.compare("33333" ); // res = -1 res = s1.compare("012345" ); // res = 0 res = s1.compare("345" ); // res = -1 res = s1.compare(0, 5, s2); // res = -1 res = s2.compare(0, 5, s1); // res = -1 res = s1.compare(0, 5, "012345" ); // res = -1 res = s2.compare(s1); // res = 1 res = s2.compare("456" ); // res = -1 res = s2.compare("000000" ); // res = 1
15. Получение строки с символом конца строки ‘\0’ (char * ). Функция c_str() . Пример

Чтобы получить строку, которая заканчивается символом ‘\0’ используется функция c_str() .

Прототип функции:

const char * c_str() const ;

Функция объявлена с модификатором const . Это означает, что функция не может изменять вызывающий объект (строку).

Пример 1 . Преобразование типа string в const char * .

// тип string, функция c_str() string s = "abcdef" ; const char * ps; ps = s.c_str(); // ps = "abcdef"

Пример 2.

Ниже продемонстрирован перевод строки из string в тип System::String для отображения его в элементе управления типа Label

Строки в C++

Строка - последовательность (массив) символов. Если в выражении встречается одиночный символ, он должен быть заключен в одинарные кавычки . При использовании в выражениях строка заключается в двойные кавычки. Признаком конца строки является нулевой символ \0 . В C++ строки можно описать с помощью символов (массив элементов типа char ), в котором следует предусмотреть место для хранения признака конца строки.

Например, описание строки из 25 символов должно выглядеть так:

Можно описать и массив строк:

Определен массив из 3 строк по 25 байт в каждой.

Для работы с указателями можно использовать (char * ). Адрес первого символа будет начальным значением указателя.

Рассмотрим пример объявления и вывода строк.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include «stdafx.h»
#include
using namespace std;
int main()
{
setlocale(LC_ALL,«Rus» ) ;
//описываем 3 строки, s3- указатель
char s2[ 20 ] , * s3, s4[ 30 ] ;
cout << «s2=» ; cin >> s2; //ввод строки s2
cout << «s2=» << s2<< endl;
//запись в s3 адреса строки, где хранится s4. Теперь в переменных
//(указателях) s3 и s4 хранится значение одного и того же адреса
s3= s4;
cout << «s3=» ; cin >> s3; //ввод строки s3
//вывод на экран строк s3 и s4, хотя в результате присваивния s3=s4;
//теперь s3 и s4 — это одно и тоже
cout << «s3=» << s3<< endl;
cout << «s4=» << s4<< endl;
system («pause» ) ;
return 0 ;
}

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

Но следует отметить, что если пользователь введет в одну переменную слова разделенные пробелом, то программа будет работать иначе:

Все дело в том, что функция cin вводит строки до встретившегося пробела. Более универсальной функцией является getline .

cin.getline(char *s, int n);

Предназначена для ввода с клавиатуры строки s с пробелами, в строке не должно быть более n символов. Следовательно, для корректного ввода строк, содержащих пробел, необходимо в нашей программе заменить cin>>s на cin.getline(s, 80) .

Операции над строками

Строку можно обрабатывать как массив символов, используя алгоритмы обработки массивов или с помощью специальных функций обработки строк, некоторые из которых приведены ниже. Для работы с этими строками необходимо подключить библиотеку cstring .

Для преобразования числа в строку можно воспользоваться функцией sprintf из библиотеки stdio.h .

Некоторые функции работы со строками:

Прототип функции Описание функции
size_t strlen(const char *s) вычисляет длину строки s в байтах.
char *strcat(char *dest, const char *scr) присоединяет строку src в конец строки dest, полученная срока возвращается в качестве результата
char *strcpy(char *dest, const char *scr) копирует строку scr в место памяти, на которое указывает dest
char strncat(char *dest, const char *dest, size_t maxlen) присоединяет строку maxlen символов строки src в конец строки dest
char *strncpy(char *dest, const char *scr, size_t maxlen) копирует maxlen символов строки src в место памяти, на которое указывает dest
int ctrcmp(const char *s1, const char *s2) сравнивает две строки в лексикографическом порядке с учетом различия прописных и строчных букв, функция возвращает 0, если строки совпадают, возвращает - 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 - в противоположном случае.
int strncmp(const char *s1, const char *s2, size_t maxlen) сравнивает maxlen символов двух строк в лексикографическом порядке, функция возвращает 0, если строки совпадают, возвращает - 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 - в противоположном случае.
double atof(const char *s) преобразует строку в вещественное число, в случае неудачного преобразования возвращается число 0
long atol(const char *s) преобразует строку в длинное целое число, в случае неудачного преобразования возвращается 0
char *strchr(const char *s, int c); возвращает указатель на первое вхождение символа c в строку, на которую указывает s . Если символ c не найден, возвращается NULL
char *strupr(char *s) преобразует символы строки, на которую указывает s, в символы верхнего регистра, после чего возвращает ее

Тип данных string

Кроме работы со строками, как с массивом символов, в C++ существует специальный тип данных string . Для ввода переменных этого типа можно использовать cin , или специальную функцию getline .

getline(cin, s);

Здесь s - имя вводимой переменной типа string .

При описании переменной этого типа можно сразу присвоить значение этой переменной.

string var(s);

Здесь var - имя переменной, s - строковая константа. В результате этого оператора создается переменная var типа string , и в нее записывается значение строковой константы s . Например,

string v(«Hello»);

Создается строка v , в которую записывается значение Hello .

Доступ к i-му элементу строки s типа string осуществляется стандартным образом s[i] . Над строками типа string определенны следующие операции:

  • присваивания, например s1=s2;
  • объединения строк (s1+=s2 или s1=s1+s2) - добавляет к строке s1 строку s2, результат храниться в строке s1, пример объединения строк:
  • сравнения строк на основе лексикографического порядка: s1=s2, s1!=s2, s1s2, s1<=s2, s1>=s2 - результатом будет логическое значение;

При обработке строк типа string можно использовать следующие функции:

  • s.substr(pos, length) - возвращает подстроку из строки s , начиная с номера pos длинной length символов;
  • s.empty() - возвращает значение true, если строка s пуста, false - в противном случае;
  • s.insert(pos, s1) - вставляет строку s1 в строку s , начиная с позиции pos ;
  • s.remove(pos, length) - удаляет из строки s подстроку length длинной pos символов;
  • s.find(s1, pos) - возвращает номер первого вхождения строки s1 в строку s , поиск начинается с номера pos , параметр pos может отсутствовать, в этом случае поиск идет с начала строки;
  • s.findfirst(s1, pos) - возвращает номер первого вхождения любого символа из строки s1 в строку s , поиск начинается с номера pos , который может отсутствовать.

Русский язык для строк

Думаю вы уже заметили, что при выводе русских букв, в консоли появляются «левые» символы. Для того чтобы избежать этого недоразумения, необходимо воспользоваться сторонней функцией CharToOemA . Подключаем библиотеку windows.h , она нужна для того, чтобы наша функция могла преобразовать строки в другую кодировку. Также, нам понадобиться дополнительный символьный массив. Исходный код программы будет выглядеть вот так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#include «stdafx.h»
#include
#include
using namespace std;
int main()
{ setlocale(LC_ALL,«Rus» ) ;
char s[ 255 ] = { » Меня надо преобразовать « } ;
char * pre= new char [ 255 ] ;
CharToOemA(s, pre) ; //преобразовываем
cout << s;
delete pre;
system («pause>>void» ) ;
return 0 ;
}

Способ только что описанный достаточно не удобен. Но существует более простой вариант решения «русской» проблемы. Как видите, в программе используется функция setlocale(), вместо этого удобнее вписать в главную функцию следующую конструкцию.

Программист говорит:

Здравствуйте! Я прочел вашу статью. Мне было очень грустно и одновременно смешно. Особенно убивает эта ваша фраза: «Так как переменную типа char часто используют как массив, то определяют количество возможных значений». 😆 😆 😆
Я не смеюсь над вами. Создание сайта это действительно подвиг. Я лишь хочу поддержать вас советом и указать несколько ошибок.

1. Значение переменной типа char присваивается так:

Вот здесь:

Char a = *"A";

Происходит разадресация указателя на массив и в результате возвращается значение первого элемента массива т.е. ‘A’

2. Обнуление происходит так:

Char a = NULL;
char b = {};

//А так очищается строка в теле программы

"" -- этот символ называется ноль-терминатор. Он ставится в конце строки. Вы сами того не зная заполнили этим символом массив s1 из вашей статьи. А ведь можно было присвоить этот символ только нулевому элементу массива.

3. Смело пользуитесь терминологией.
Знак = это операция присваивания.
Знак * операция разадресации.
Я имею в виду вот этот фрагмент статьи: "Настолько всё оказалось просто, перед знаком = нужно было поставить знак * и нужно было объявить номер элемента (ноль соответствует первому)"

Поймите меня правильно, статья в нынешнем виде не может существовать. Не поленитесь, перепишите ее.
На вас лежит большая ответственность! Я серьезно. Страницы вашего сайта попали в первую страницу выдачи Яндекса. Много людей уже начали повторять за вами ошибки.

Удачи! Вы справитесь!

:
Я это давно знаю, просто трудно перечитывать 200 статей постоянно, чтобы что-то исправить. А некоторые грубые типы так пишут, что даже зная, что лучше исправить, исправлять совсем не охота.

Я буду рад исправить и другие ошибки. поправить неточности, если они выскочат. Я ценю вашу помощь. спасибо.Я это давно знаю, просто трудно перечитывать 200 статей постоянно, чтобы что-то исправить. А некоторые грубые типы так пишут, что даже зная, что лучше исправить, исправлять совсем не охота.
С вашим char b = {}; Это не обнуление совсем. проверили бы хотя б.
если говорить о нулевом символе "" ; Я хорошо знал, когда заполнял им строку и цель была в том, чтобы показать настоящее очищение, а не видимое на глаз, ибо в строку входит мусор, который иногда мешает. Вы бы с терминами сами поаккуратнее, "символ нуль-терминации" или просто "нулевой символ", не терминатор))) А символ-терминатор звучит просто круто.

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

Я буду рад исправить и другие ошибки. поправить неточности, если они выскочат. Я ценю вашу помощь. спасибо.

Здравствуйте еще раз!
Хочу пояснить. Термином "ноль-терминатор" (terminator с англ. ограничитель) пользовался мой преподаватель в ВУЗе. Видимо это old school!
Что касается обнуления строк.
char b = {}; Это действительно обнуление. Весь массив заполнен нулями. Не верите -- проверьте!
Если рассматривать строку в её естественном, бытовом смысле, то "пустой" будет та строка в которой нет ни одного символа. Поэтому в 99.9% случаев достаточно поставить в начало нулевой символ. Обычно обработка строки идет до первого нулевого символа а какие символы идут за ним уже не важно. Я понимаю что вы хотели обнулить строку. Просто решил предложить проверенный временем классический вариант.

:
Когда "Обычно обработка строки идет до первого нулевого символа а какие символы идут за ним уже не важно" - да, строка обнуляется
Если рассматривать "реальное обнуление всех ячеек строки (о котором писал я)" - нет, не обнуление и, даже, первый символ не нулевой. Я этим вариантом проверял. MinGW(CodeBlock) - весь массив отдает символ "a"
не думаю, что это повод для споров.

34

--- Руководство по C# --- Строки

С точки зрения регулярного программирования строковый тип данных string относится к числу самых важных в C#. Этот тип определяет и поддерживает символьные строки. В целом ряде других языков программирования строка представляет собой массив символов. А в C# строки являются объектами. Следовательно, тип string относится к числу ссылочных.

Построение строк

Самый простой способ построить символьную строку - воспользоваться строковым литералом . Например, в следующей строке кода переменной ссылки на строку str присваивается ссылка на строковый литерал:

String str = "Пример строки";

В данном случае переменная str инициализируется последовательностью символов "Пример строки". Объект типа string можно также создать из массива типа char. Например:

Char chararray = {"e", "x", "a", "m", "p", "l", "e"}; string str = new string(chararray);

Как только объект типа string будет создан, его можно использовать везде, где только требуется строка текста, заключенного в кавычки.

Постоянство строк

Как ни странно, содержимое объекта типа string не подлежит изменению. Это означает, что однажды созданную последовательность символов изменить нельзя. Но данное ограничение способствует более эффективной реализации символьных строк. Поэтому этот, на первый взгляд, очевидный недостаток на самом деле превращается в преимущество. Так, если требуется строка в качестве разновидности уже имеющейся строки, то для этой цели следует создать новую строку, содержащую все необходимые изменения. А поскольку неиспользуемые строковые объекты автоматически собираются в "мусор", то о дальнейшей судьбе ненужных строк можно даже не беспокоиться.

Следует, однако, подчеркнуть, что переменные ссылки на строки (т.е. объекты типа string) подлежат изменению, а следовательно, они могут ссылаться на другой объект. Но содержимое самого объекта типа string не меняется после его создания.

Рассмотрим пример:

Static void addNewString() { string s = "This is my stroke"; s = "This is new stroke"; }

Скомпилируем приложение и загрузим результирующую сборку в утилиту ildasm.exe . На рисунке показан CIL-код, который будет сгенерирован для метода void addNewString():

Обратите внимание на наличие многочисленных вызовов кода операции ldstr (загрузка строки). Этот код операции ldstr в CIL предусматривает выполнение загрузки нового объекта string в управляемую кучу. В результате предыдущий объект, в котором содержалось значение "This is my stroke", будет в конечном итоге удален сборщиком мусора.

Работа со строками

В классе System.String предоставляется набор методов для определения длины символьных данных, поиска подстроки в текущей строке, преобразования символов из верхнего регистра в нижний и наоборот, и т.д. Далее мы рассмотрим этот класс более подробно.

Поле, индексатор и свойство класса String

В классе String определено единственное поле:

Public static readonly string Empty;

Поле Empty обозначает пустую строку, т.е. такую строку, которая не содержит символы. Этим оно отличается от пустой ссылки типа String, которая просто делается на несуществующий объект.

Помимо этого, в классе String определен единственный индексатор, доступный только для чтения:

Public char this { get; }

Этот индексатор позволяет получить символ по указанному индексу. Индексация строк, как и массивов, начинается с нуля. Объекты типа String отличаются постоянством и не изменяются, поэтому вполне логично, что в классе String поддерживается индексатор, доступный только для чтения.

И наконец, в классе String определено единственное свойство, доступное только для чтения:

Public int Length { get; }

Свойство Length возвращает количество символов в строке. В примере ниже показано использование индексатора и свойства Length:

Using System; class Example { static void Main() { string str = "Простая строка"; // Получить длину строки и 6й символ в строке используя индексатор Console.WriteLine("Длина строки - {0}, 6й символ - "{1}"", str.Length, str); } }

Операторы класса String

В классе String перегружаются два следующих оператора: == и!=. Оператор == служит для проверки двух символьных строк на равенство. Когда оператор == применяется к ссылкам на объекты, он обычно проверяет, делаются ли обе ссылки на один и тот же объект. А когда оператор == применяется к ссылкам на объекты типа String, то на предмет равенства сравнивается содержимое самих строк. Это же относится и к оператору!=. Когда он применяется к ссылкам на объекты типа String, то на предмет неравенства сравнивается содержимое самих строк. В то же время другие операторы отношения, в том числе =, сравнивают ссылки на объекты типа String таким же образом, как и на объекты других типов. А для того чтобы проверить, является ли одна строка больше другой, следует вызвать метод Compare(), определенный в классе String.

Как станет ясно дальше, во многих видах сравнения символьных строк используются сведения о культурной среде. Но это не относится к операторам == и!=. Ведь они просто сравнивают порядковые значения символов в строках. (Иными словами, они сравнивают двоичные значения символов, не видоизмененные нормами культурной среды, т.е. региональными стандартами.) Следовательно, эти операторы выполняют сравнение строк без учета регистра и настроек культурной среды.

Методы класса String

В следующей таблице перечислены некоторые наиболее интересные методы этого класса, сгруппированные по назначению:

Методы работы со строками
Метод Структура и перегруженные версии Назначение
Сравнение строк
Compare() public static int Compare(string strA, string strB)

Public static int Compare(string strA, string strB, bool ignoreCase)

Public static int Compare(string strA, string strB, StringComparison comparisonType)

Public static int Compare(string strA, string strB, bool ignoreCase, CultureInfo culture)

Статический метод, сравнивает строку strA со строкой strB. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды.

Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются.

Параметр comparisonType определяет конкретный способ сравнения строк. Класс CultureInfo определен в пространстве имен System.Globalization.

public static int Compare(string strA, int indexA, string strB, int indexB, int length)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, StringComparison comparisonType)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase, CultureInfo culture)

Сравнивает части строк strA и strB. Сравнение начинается со строковых элементов strA и strB и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды.

CompareOrdinal() public static int CompareOrdinal(string strA, string strB)

Public static int CompareOrdinal(string strA, int indexA, string strB, int indexB, int count)

Делает то же, что и метод Compare(), но без учета локальных установок

CompareTo() public int CompareTo(object value)

Сравнивает вызывающую строку со строковым представлением объекта value. Возвращает положительное значение, если вызывающая строка больше строки value; отрицательное значение, если вызывающая строка меньше строки value; и нуль, если сравниваемые строки равны

public int CompareTo(string strB)

Сравнивает вызывающую строку со строкой strB

Equals() public override bool Equals(object obj)

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

public bool Equals(string value)

Public bool Equals(string value, StringComparison comparisonType)

Возвращает логическое значение true, если вызывающая строка содержит ту же последовательность символов, что и строка value. Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды. Параметр comparisonType определяет конкретный способ сравнения строк

public static bool Equals(string a, string b)

Public static bool Equals(string a, string b, StringComparison comparisonType)

Возвращает логическое значение true, если строка a содержит ту же последовательность символов, что и строка b . Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды. Параметр comparisonType определяет конкретный способ сравнения строк

Конкатенация (соединение) строк
Concat() public static string Concat(string str0, string str1);

public static string Concat(params string values);

Комбинирует отдельные экземпляры строк в одну строку (конкатенация)
Поиск в строке
Contains() public bool Contains(string value) Метод, который позволяет определить, содержится ли в строке определенная подстрока (value)
StartsWith() public bool StartsWith(string value)

Public bool StartsWith(string value, StringComparison comparisonType)

Возвращает логическое значение true, если вызывающая строка начинается с подстроки value. В противном случае возвращается логическое значение false. Параметр comparisonType определяет конкретный способ выполнения поиска

EndsWith() public bool EndsWith(string value)

Public bool EndsWith(string value, StringComparison comparisonType)

Возвращает логическое значение true, если вызывающая строка оканчивается подстрокой value. В противном случае возвращает логическое значение false. Параметр comparisonType определяет конкретный способ поиска

IndexOf() public int IndexOf(char value)

Public int IndexOf(string value)

Находит первое вхождение заданной подстроки или символа в строке. Если искомый символ или подстрока не обнаружены, то возвращается значение -1

public int IndexOf(char value, int startIndex)

Public int IndexOf(string value, int startIndex)

Public int IndexOf(char value, int startIndex, int count)

Public int IndexOf(string value, int startIndex, int count)

Возвращает индекс первого вхождения символа или подстроки value в вызывающей строке. Поиск начинается с элемента, указываемого по индексу startIndex, и охватывает число элементов, определяемых параметром count (если указан). Метод возвращает значение -1, если искомый символ или подстрока не обнаружен

LastIndexOf() Перегруженные версии аналогичны методу IndexOf()

То же, что IndexOf, но находит последнее вхождение символа или подстроки, а не первое

IndexOfAny() public int IndexOfAny(char anyOf)

Public int IndexOfAny(char anyOf, int startIndex)

Public int IndexOfAny(char anyOf, int startIndex, int count)

Возвращает индекс первого вхождения любого символа из массива anyOf, обнаруженного в вызывающей строке. Поиск начинается с элемента, указываемого по индексу startIndex, и охватывает число элементов, определяемых параметром count (если они указаны). Метод возвращает значение -1, если не обнаружено совпадение ни с одним из символов из массива anyOf. Поиск осуществляется порядковым способом

LastIndexOfAny Перегруженные версии аналогичны методу IndexOfAny()

Возвращает индекс последнего вхождения любого символа из массива anyOf, обнаруженного в вызывающей строке

Разделение и соединение строк
Split public string Split(params char separator)

Public string Split(params char separator, int count)

Метод, возвращающий массив string с присутствующими в данном экземпляре подстроками внутри, которые отделяются друг от друга элементами из указанного массива char или string.

В первой форме метода Split() вызывающая строка разделяется на составные части. В итоге возвращается массив, содержащий подстроки, полученные из вызывающей строки. Символы, ограничивающие эти подстроки, передаются в массиве separator. Если массив separator пуст или ссылается на пустую строку, то в качестве разделителя подстрок используется пробел. А во второй форме данного метода возвращается количество подстрок, определяемых параметром count.

public string Split(params char separator, StringSplitOptions options)

Public string Split(string separator, StringSplitOptions options)

Public string Split(params char separator, int count, StringSplitOptions options)

Public string Split(string separator, int count, StringSplitOptions options)

В двух первых формах метода Split() вызывающая строка разделяется на части и возвращается массив, содержащий подстроки, полученные из вызывающей строки. Символы, разделяющие эти подстроки, передаются в массиве separator. Если массив separator пуст, то в качестве разделителя используется пробел. А в третьей и четвертой формах данного метода возвращается количество строк, ограничиваемое параметром count.

Но во всех формах параметр options обозначает конкретный способ обработки пустых строк, которые образуются в том случае, если два разделителя оказываются рядом. В перечислении StringSplitOptions определяются только два значения: None и RemoveEmptyEntries . Если параметр options принимает значение None, то пустые строки включаются в конечный результат разделения исходной строки. А если параметр options принимает значение RemoveEmptyEntries, то пустые строки исключаются из конечного результата разделения исходной строки.

Join() public static string Join(string separator, string value)

Public static string Join(string separator, string value, int startIndex, int count)

Строит новую строку, комбинируя содержимое массива строк.

В первой форме метода Join() возвращается строка, состоящая из сцепляемых подстрок, передаваемых в массиве value. Во второй форме также возвращается строка, состоящая из подстрок, передаваемых в массиве value, но они сцепляются в определенном количестве count, начиная с элемента массива value. В обеих формах каждая последующая строка отделяется от предыдущей разделительной строкой, определяемой параметром separator.

Заполнение и обрезка строк
Trim() public string Trim()

Public string Trim(params char trimChars)

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

В первой форме метода Trim() из вызывающей строки удаляются начальные и конечные пробелы. А во второй форме этого метода удаляются начальные и конечные вхождения в вызывающей строке символов из массива trimChars. В обеих формах возвращается получающаяся в итоге строка.

PadLeft() public string PadLeft(int totalWidth)

Public string PadLeft(int totalWidth, char paddingChar)

Позволяет дополнить строку символами слева.

В первой форме метода PadLeft() вводятся пробелы с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. А во второй форме данного метода символы, обозначаемые параметром paddingChar, вводятся с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. В обеих формах возвращается получающаяся в итоге строка. Если значение параметра totalWidth меньше длины вызывающей строки, то возвращается копия неизмененной вызывающей строки.

PadRight() Аналогично PadLeft()

Позволяет дополнить строку символами справа.

Вставка, удаление и замена строк
Insert() public string Insert(int startIndex, string value)

Используется для вставки одной строки в другую, где value обозначает строку, вставляемую в вызывающую строку по индексу startIndex. Метод возвращает получившуюся в итоге строку.

Remove() public string Remove(int startIndex)

Public string Remove(int startIndex, int count)

Используется для удаления части строки. В первой форме метода Remove() удаление выполняется, начиная с места, указываемого по индексу startIndex, и продолжается до конца строки. А во второй форме данного метода из строки удаляется количество символов, определяемое параметром count, начиная с места, указываемого по индексу startIndex.

Replace() public string Replace(char oldChar, char newChar)

Public string Replace(string oldValue, string newValue)

Используется для замены части строки. В первой форме метода Replace() все вхождения символа oldChar в вызывающей строке заменяются символом newChar. А во второй форме данного метода все вхождения строки oldValue в вызывающей строке заменяются строкой newValue.

Смена регистра
ToUpper() public string ToUpper()

Делает заглавными все буквы в вызывающей строке.

ToLower() public string ToLower()

Делает строчными все буквы в вызывающей строке.

Получение подстроки из строки
Substring() public string Substring(int startIndex)

Public string Substring(int startIndex, int length)

В первой форме метода Substring() подстрока извлекается, начиная с места, обозначаемого параметром startIndex, и до конца вызывающей строки. А во второй форме данного метода извлекается подстрока, состоящая из количества символов, определяемых параметром length, начиная с места, обозначаемого параметром startIndex.

Пример следующей программы использует несколько из вышеуказанных методов:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { // Сравним первые две строки string s1 = "это строка"; string s2 = "это текст, а это строка"; if (String.CompareOrdinal(s1, s2) != 0) Console.WriteLine("Строки s1 и s2 не равны"); if (String.Compare(s1, 0, s2, 13, 10, true) == 0) Console.WriteLine("При этом в них есть одинаковый текст"); // Конкатенация строк Console.WriteLine(String.Concat("\n" + "Один, два ","три, четыре")); // Поиск в строке // Первое вхождение подстроки if (s2.IndexOf("это") != -1) Console.WriteLine("Слово \"это\" найдено в строке, оно "+ "находится на: {0} позиции", s2.IndexOf("это")); // Последнее вхождение подстроки if (s2.LastIndexOf("это") != -1) Console.WriteLine("Последнее вхождение слова \"это\" находится " + "на {0} позиции", s2.LastIndexOf("это")); // Поиск из массива символов char myCh = {"Ы","х","т"}; if (s2.IndexOfAny(myCh) != -1) Console.WriteLine("Один из символов из массива ch "+ "найден в текущей строке на позиции {0}", s2.IndexOfAny(myCh)); // Определяем начинается ли строка с заданной подстроки if (s2.StartsWith("это текст") == true) Console.WriteLine("Подстрока найдена!"); // Определяем содержится ли в строке подстрока // на примере определения ОС пользователя string myOS = Environment.OSVersion.ToString(); if (myOS.Contains("NT 5.1")) Console.WriteLine("Ваша операционная система Windows XP"); else if (myOS.Contains("NT 6.1")) Console.WriteLine("Ваша операционная система Windows 7"); Console.ReadLine(); } } }

Немного о сравнении строк в C#

Вероятно, из всех операций обработки символьных строк чаще всего выполняется сравнение одной строки с другой. Прежде чем рассматривать какие-либо методы сравнения строк, следует подчеркнуть следующее: сравнение строк может быть выполнено в среде.NET Framework двумя основными способами:

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

    И во-вторых, сравнение может быть выполнено независимо от настроек культурной среды только по порядковым значениям символов, составляющих строку. Вообще говоря, при сравнении строк без учета культурной среды используется лексикографический порядок (и лингвистические особенности), чтобы определить, является ли одна строка больше, меньше или равной другой строке. При порядковом сравнении строки просто упорядочиваются на основании невидоизмененного значения каждого символа.

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

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

В классе String предоставляются самые разные методы сравнения строк, которые перечислены в таблице выше. Наиболее универсальным среди них является метод Compare(). Он позволяет сравнивать две строки полностью или частично, с учетом или без учета регистра, способа сравнения, определяемого параметром типа StringComparison , а также сведений о культурной среде, предоставляемых с помощью параметра типа CultureInfo .

Те перегружаемые варианты метода Compare(), которые не содержат параметр типа StringComparison, выполняют сравнение символьных строк с учетом регистра и культурной среды. А в тех перегружаемых его вариантах, которые не содержат параметр типа CultureInfo, сведения о культурной среде определяются текущей средой выполнения.

Тип StringComparison представляет собой перечисление, в котором определяются значения, приведенные в таблице ниже. Используя эти значения, можно организовать сравнение строк, удовлетворяющее потребностям конкретного приложения. Следовательно, добавление параметра типа StringComparison расширяет возможности метода Compare() и других методов сравнения, например, Equals(). Это дает также возможность однозначно указывать способ предполагаемого сравнения строк.

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

Значения, определяемые в перечислении StringComparison
Значение Описание
CurrentCulture Сравнение строк производится с использованием текущих настроек параметров культурной среды
CurrentCultureIgnoreCase Сравнение строк производится с использованием текущих настроек параметров культурной среды, но без учета регистра
InvariantCulture Сравнение строк производится с использованием неизменяемых, т.е. универсальных данных о культурной среде
InvariantCultureIgnoreCase Сравнение строк производится с использованием неизменяемых, т.е. универсальных данных о культурной среде и без учета регистра
Ordinal Сравнение строк производится с использованием порядковых значений символов в строке. При этом лексикографический порядок может нарушиться, а условные обозначения, принятые в отдельной культурной среде, игнорируются
OrdinalIgnoreCase Сравнение строк производится с использованием порядковых значений символов в строке, но без учета регистра

В любом случае метод Compare() возвращает отрицательное значение, если первая сравниваемая строка оказывается меньше второй; положительное значение, если первая сравниваемая строка больше второй; и наконец, нуль, если обе сравниваемые строки равны. Несмотря на то что метод Compare() возвращает нуль, если сравниваемые строки равны, для определения равенства символьных строк, как правило, лучше пользоваться методом Equals() или же оператором ==.

Дело в том, что метод Compare() определяет равенство сравниваемых строк на основании порядка их сортировки. Так, если выполняется сравнение строк с учетом культурной среды, то обе строки могут оказаться одинаковыми по порядку их сортировки, но не равными по существу. По умолчанию равенство строк определяется в методе Equals(), исходя из порядковых значений символов и без учета культурной среды. Следовательно, по умолчанию обе строки сравниваются в этом методе на абсолютное, посимвольное равенство подобно тому, как это делается в операторе ==.

Несмотря на большую универсальность метода Compare(), для простого порядкового сравнения символьных строк проще пользоваться методом CompareOrdinal(). И наконец, следует иметь в виду, что метод CompareTo() выполняет сравнение строк только с учетом культурной среды.

В приведенной ниже программе демонстрируется применение методов Compare(), Equals(), CompareOrdinal(), а также операторов == и!= для сравнения символьных строк. Обратите внимание на то, что два первых примера сравнения наглядно демонстрируют отличия между сравнением строк с учетом культурной среды и порядковым сравнением в англоязычной среде:

Using System; class Example { static void Main() { string str1 = "alpha"; string str2 = "Alpha"; string str3 = "Beta"; string str4 = "alpha"; string str5 = "alpha, beta"; int result; // Сначала продемонстрировать отличия между сравнением строк // с учетом культурной среды и порядковым сравнением result = String.Compare(str1, str2, StringComparison.CurrentCulture); Console.Write("Сравнение строк с учетом культурной среды: "); if (result 0) Console.WriteLine(str1 + " больше " + str2); else Console.WriteLine(str1 + " равно " + str2); result = String.Compare(str1, str2, StringComparison.Ordinal); Console.Write("Порядковое сравнение строк: "); if (result 0) Console.WriteLine(str1 + " больше " + str2); else Console.WriteLine(str1 + " равно " + str4); // Использовать метод CompareOrdinal() result = String.CompareOrdinal(str1, str2); Console.Write("Сравнение строк методом CompareOrdinal():\n"); if (result 0) Console.WriteLine(str1 + " больше " + str2); else Console.WriteLine(str1 + " равно " + str4); Console.WriteLine(); // Определить равенство строк с помощью оператора == // Это порядковое сравнение символьных строк if (str1 == str4) Console.WriteLine(str1 + " == " + str4); // Определить неравенство строк с помощью оператора!= if(str1 != str3) Console.WriteLine(str1 + " != " + str3); if(str1 != str2) Console.WriteLine(str1 + " != " + str2); Console.WriteLine(); // Выполнить порядковое сравнение строк без учета регистра, // используя метод Equals() if(String.Equals(str1, str2, StringComparison.OrdinalIgnoreCase)) Console.WriteLine("Сравнение строк методом Equals() с " + "параметром OrdinalIgnoreCase:\n" + str1 + " равно " + str2); Console.WriteLine (); // Сравнить части строк if(String.Compare(str2, 0, str5, 0, 3, StringComparison.CurrentCulture) > 0) { Console.WriteLine("Сравнение строк с учетом текущей культурной среды:" + "\n3 первых символа строки " + str2 + " больше, чем 3 первых символа строки " + str5); } } }

Выполнение этой программы приводит к следующему результату:



Загрузка...