Ломается программа при вводе con
Проблема такая, преподаватель ввел con и все сломалось. Нужно сделать, чтобы программа не ломалась при вводе con, не знаю как это сделать....
#include <iostream>
#include <fstream>
using namespace std;
char ruski[][32] = { "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ", "абвгдеёжзийклмнопрстуфхцчшщыэюя" };
char eng[][5] = { "A", "B", "V", "G", "D", "E", "E", "ZH", "Z", "I", "Y", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", "KH", "TS", "CH", "SH", "SHCH", "Y", "E", "YU", "YA" };
char ruski1[] = "ЪъЬь";
int srch(char* s, char ch)
{
int i = 0;
while (s[i] != '\0')
{
if (s[i] == ch)
{
return i;
}
i++;
}
return -1;
}
int main()
{
setlocale(LC_ALL, "Rus");
char fname[100];
cout << "Укажите файл, пожалуйста: ";
cin.getline(fname, 100);
ifstream sr(fname);
if (!sr.is_open())
{
cout << "\nТакого файла нету\n\n";
}
else
{
ofstream sw("res.txt");
if (!sw.is_open())
{
cout << "\nНе создаётся файл\n\n";
}
else
{
int k;
char ch;
while (!sr.eof())
{
sr.get(ch);
if (sr.eof())
{
break;
}
k = srch(ruski[0], ch);
if (k < 0)
{
k = srch(ruski[1], ch);
}
if (k >= 0)
{
cout << eng[k];
sw << eng[k];
}
else
{
if (srch(ruski1, ch) < 0)
{
cout << ch;
sw << ch;
}
}
}
cout << "\nВсё\nНу и результат записан в \"res.txt\"\n\n";
sw.close();
}
sr.close();
}
cin.get();
return 0;
system("pause");
}
Ответы (1 шт):
Автор решения: TheRyuTeam
→ Ссылка
Проблемы:
- Русский символ != 1 байт, т.е длинна русского алфавита (без ь, Ъ) в char будет 63.
- Все зависит от кодировки файла, который читаешь (например, при utf-8 у меня первый символ = 208, т.е в данной кодировке файла кириллица кодируется ДВУМЯ байтами, если файл в Windows-1251 - символ = 192). Т.е Ваш вариант поиска не работает с utf-8!
- Так же кодировка исходника должна совпадать с кодировкой читаемого файла. Например - файл для чтения в Windows-1251, а исходник в utf-8 - поиск НЕ СРАБОТАЕТ!
Варианты решения:
- Условливаемся, что кодировка входного файла - какая-то конкретная(например utf-8)
- Используя эту статью анализируем данные, определяем кодировку файла, работаем с определенной кодировкой
Как сделал я:
Выставил кодировку входного файла в utf-8. Запустил этот код под отладкой:
#include <iostream>
#include <fstream>
using namespace std;
const char russianUpper[] = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ";
const char russianLower[] = "абвгдеёжзийклмнопрстуфхцчшщыэюя";
const char englishAnalogue[][5] = {
"A", "B", "V", "G", "D", "E", "E", "ZH", "Z", "I", "Y", "K", "L", "M", "N", "O",
"P", "R", "S", "T", "U", "F", "KH", "TS", "CH", "SH", "SHCH", "Y", "E", "YU", "YA"
};
int srch(const char* s, char fb, char sb)
{
for (int i = 0; s[i + 1] != '\0'; i += 2)
{
if (s[i] == fb && s[i + 1] == sb)
return i / 2;
}
return -1;
}
int main()
{
setlocale(LC_ALL, "Rus");
char fname[100];
cout << "Укажите файл, пожалуйста: ";
cout.flush();
cin.getline(fname, 100);
ifstream sr(fname);
if (!sr.is_open())
{
cout << "Can not open \"" << fname << "\".";
return -1;
}
ofstream sw("res.txt");
if (!sw.is_open())
{
cout << "Can not create output file.\n";
return -2;
}
while (true)
{
const char ch = sr.get();
if (sr.eof())
break;
// If first byte is russian first byte (utf-8 only)
if (ch == -48 || ch == -49)
{
// Russian second byte
const char sch = sr.get();
int k = srch(russianUpper, ch, sch);
if (k < 0)
k = srch(russianLower, ch, sch);
if (k >= 0)
{
cout << englishAnalogue[k];
sw << englishAnalogue[k];
}
}
else
{
cout << ch;
sw << ch;
}
}
sw.close();
sr.close();
cout << "\nJobs done!\nResult is in \"res.txt\".\n";
return 0;
}
Как это работает: зная, что кириллица в utf-8 занимает 2 байта и первый байт - гарантированно 208 или 209, смотрим первый байт - если русский - читаем второй и ищем в алфавите, иначе просто выводим.