Visual C++: кириллица в консоли и поиск кириллицы
Этот небольшой учебный пример класса (Visual Studio) иллюстрирует следующие действия:
- простейшее консольное меню, без борландо-специфичных функций консоли из
conio.h
(а как всё-таки сделать по-борландовски?); - загрузка данных из файла в динамически сформированные массивы - свойства класса (а вообще-то, не забывайте что есть более современные методы из библиотеки
<fstream>
); - ввод и вывод кириллицы в консоли; если при первом запуске программы видите всё-таки "кракозябры" вместо русских букв, прочитайте комментарий в начале файла (как сменить шрифт консоли на Lucida Console);
- поиск строк кириллицы без учёта регистра символов и с возможным неполным соответствием (методы
find
,strstr
,lowercase
).
Вот полный исходник примера:
//Вставьте этот файл в пустой проект Visual C++ //Если при запуске программы в консоли не видно русского текста - щёлкните по кнопке системного меню //окна консоли, выберите пункт меню Свойства, вкладку Шрифт и установите Lucida Console. //Файл данных data.txt закодирован в Windows-1251 (русская Windows) и находится в папке приложения, //пример файла - внутри комментария /* ... */ /* Велосипед 1500 коньки 900 */ #include <conio.h> #include <stdio.h> #include <windows.h> #include <locale.h> class Class { FILE *file; //дескриптор файла с данными char **s; //строки данных int *n; //числа с данными int len,num; //макс.длина строки и количество строк int openfile (); //служебная - открыть и прочитать файл с данными int lowercase (char); //служебная - перевод символа в нижний регистр int strstr (const char *, const char *); //служебная - поиск подстроки в строке без учёта регистра символов public: bool enabled; //доступность данных Class (); //конструктор ~Class (); //деструктор int find (char *); //поиск строки int find (int); //поиск числа char *gets(int); //получить строку с нужным номером inline int getlen () { return len; } //получить макс.длину строки }; int Class::openfile() { //считает количество строк и размер строки, выделяет память, загружает данные len = num = 0; enabled = false; file = fopen ("data.txt","rb"); if (file==NULL) return 0; int c; int kol=0; while (!feof(file)) { fread (&c,sizeof(char),1,file); kol++; if ((char)c=='\n') { if (kol>len) len=kol; kol=0; num++; } } if ((char)c!='\n') num++; //в конце не пустая строка? тогда num на 1 меньше, чем прочитали строк s = new char * [num]; len++; //с "запасом" в 1 символ for (int i=0; i<num; i++) s[i] = new char [len]; n = new int [num]; fseek (file,0,SEEK_SET); for (int i=0; i<num; i++) { fscanf (file,"%s",s[i]); fscanf (file,"%d",&n[i]); } fclose (file); enabled = true; return 1; } Class::Class () { if (!openfile()) enabled = false; } Class::~Class () { int n = this->num; delete [] this->n; for (int i=n-1; i>-1; i--) delete s[i]; delete [] s; } int Class::lowercase (char c) { const char lo[] = "abcdefqhijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя"; const char up[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; int len = strlen(up); for (int i=0; i<len; i++) if (up[i] == c) return lo[i]; return c; } int Class::strstr (const char *str, const char *p) { int i = 0; while (str) { const char * s1 = str; const char* p1 = p; while (lowercase(*s1) == lowercase(*p1)) { s1++; p1++; if (*p1 == '\0' || *s1 == '\0') break; } if (*p1 == '\0') return i; if (*s1 == '\0') return -1; str++; i++; } return -1; } int Class::find (char *s) { if (!enabled) return -1; for (int i=0; i<num; i++) { int pos = strstr(this->s[i],s); if (pos!=-1) return i; //Только первое вхождение } return -1; } int Class::find (int n) { if (!enabled) return -1; for (int i=0; i<num; i++) { if (this->n[i]==n) return i; //Только первое вхождение } return -1; } char * Class::gets (int n) { if (n>-1 && n<num) return this->s[n]; return NULL; } int main () { SetConsoleCP(1251); SetConsoleOutputCP(1251); setlocale(LC_ALL,"Russian"); char ch; Class *c = new Class(); if (c->enabled == NULL) { printf ("\nОшибка: файл data.txt не найден в папке приложения\n"); system ("pause"); return 1; } char *buf = new char [c->getlen()]; do { system("cls"); printf ("\n1. Найти строку\n2. Найти число\n0. Выход\n"); ch = getch(); int pos,n; switch (ch) { case '1': printf ("\nВведите строку для поиска: "); fflush (stdin); scanf ("%s",buf); pos = c->find (buf); if (pos!=-1) printf ("\nНайдено: %s в позиции %d\n",c->gets(pos),pos+1); else printf ("\nНе найдено\n"); break; case '2': printf ("\nВведите число для поиска: "); fflush (stdin); scanf ("%d",&n); pos = c->find (n); if (pos>-1) printf ("\nНайдено: %s в позиции %d\n",c->gets(pos),pos+1); else printf ("\nНе найдено\n"); break; case '0': return 0; default: break; } system ("pause"); } while (ch!=27); delete buf; delete c; return 0; }
23.04.2015, 11:33 [11035 просмотров]