Программа не работает с кириллицей С++

144
22 июля 2022, 05:40

Делаю курсовой проект по теме поиска подстроки в строке с помощью алгоритма Бойера-Мура.(Главная строка должна быть больше 255 символов). Сам алгоритм вроде как работает но при использовании кириллицы выскакивает исключение: Run-Time Check Failure #2 - Stack around the variable 'badchar' was corrupted. Если его скипнуть то программа далее правильно работает и ищет. Кто знает как можно пофиксить? Делаю в visual studio 2019. P.S. Вообще все проблемы мог бы решить string вместо масива но препод запретил его использовать :) Вот весь код программы (много лишнего и на украинском так как курсач):

#include <iostream>
#include <conio.h>
#include <Windows.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include<math.h>

using namespace std;
char* Input(char*); //ввод з клавиатуры
char* StrInput(char*); //считывание с файла
char* PatInput(char*,char*);
void Processing(char*, char*); //обработка
void Output(char*, char*, int); //Вывод на экран
void FOutput(char*, char*, int); //Вивод в файл
void Counter(char*); //функция подсчета размера строки из файла
void BadCharHeuristic(char*, int, int[]);  //для алгоритма поиска
int Search(char*, char*);  //алгоритм поиска
int Max(int, int); 
int NumberOfSymbols=0; //Кількість символів в головному рядку
int main() //Головна функція програми
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    char* my_str=new  char[NumberOfSymbols];
    my_str[0] = '\0';
    char* find_str=new char[NumberOfSymbols];
    find_str[0] = '\0';
    int S = 0;
    char punkt;
label1:
    system("cls");
    cout << "1-Ввод з клавіатури" << endl << "2-Зчитати з файлу" << endl;
    cout << "3-Обробка" << endl<<"4-Обробка з файлу"<<endl<< "5-Вивод на екран" << endl;
    cout << "6-Запис в файл" << endl << "7-Про програму" << endl << "8-Вихід" << endl << endl << "ЗРОБІТЬ ВИБІР->";
    punkt = _getch();
    switch (punkt)
    {
    
    case '1':
    {
        system("cls");
        cout << "Ввод з клавіатури:" << endl;
        my_str = Input(my_str);
        find_str = new char[NumberOfSymbols];
        system("pause");
        goto label1;
    }
    case '2':
    {
        system("cls");
        cout << "Зчитати з файлу:" << endl;
        my_str = StrInput(my_str);
        find_str = new char[NumberOfSymbols];
        system("pause");
        goto label1;
    }
    case '3':
    {
        system("cls");
        cout << "Обробка:" << endl;
        Processing(my_str, find_str);
        S = Search(my_str, find_str);
        system("pause");
        goto label1;
    }
    case '4':
    {
        system("cls");
        cout << "Обробка з файлу:" << endl;
        find_str = PatInput(find_str,my_str);
        S = Search(my_str, find_str);
        system("pause");
        goto label1;
    }
    case '5':
    {
        system("cls");
        cout << "Вивод на екран" << endl;
        if (strlen(find_str) == 0)
        {
            cout << "Ви не ввели підрядок для пошуку, поверніться до пункту 3" << endl;
            system("pause");
            goto label1;
        }
        Output(my_str, find_str, S);
        system("pause");
        goto label1;
    }
    case '6':
    {
        system("cls");
        cout << "Запис в файл" << endl;
        FOutput(my_str, find_str, S);
        system("pause");
        goto label1;
    }
    case '7':
    {
        system("cls");
        cout << "Про програму" << endl;
        system("pause");
        goto label1;
    }
    case '8':
    {
        system("cls");
        cout << "Робота програми заверена! Гарного вам дня :)" << endl;
        system("pause");
        return 0;
    }
    default:
    {
        cout << endl << "Натиснуто не ту клавішу!" << endl;
        system("pause");
        goto label1;
    }
    }
    delete[] my_str;
    delete[] find_str;
    return 0;
}
char* Input(char* str)
{
    cout << "Введіть розмір рядка->";
    cin >> NumberOfSymbols;
    str = new char[NumberOfSymbols];
    cout << "Введіть головний рядок -> ";
    cin.ignore();
    gets_s(str, NumberOfSymbols);
    return str;
}
char* StrInput(char* str)
{
    char name[80];
    cout << "Введіть назву файлу->";
    gets_s(name, 80);
    ifstream fread(name);
    if (!fread.is_open())
    {
        cout << "Файл відкрити не вдалося" << endl;
    }
    else
    {
        Counter(name);
        str = new char[NumberOfSymbols];
        fread.get(str, NumberOfSymbols);
        cout << "Ви считали з файлу:" << endl;
        cout << str << endl;
    }
    fread.close();
    return str;
}
char* PatInput(char* pat,char*txt)
{
    char name[80];
    cout << "Введіть назву файлу->";
    gets_s(name, 80);
    ifstream fread(name);
    if (!fread.is_open())
    {
        cout << "Файл відкрити не вдалося" << endl;
    }
    else
    {
        Counter(name);
        pat = new char[NumberOfSymbols];
        fread.get(pat, NumberOfSymbols);
        while ((strlen(txt) <= strlen(pat) || strlen(pat) == 0))
        {
            cout << "Сталася помилка. Можливо ви не ввели текст або ви ввели текст більший за головний рядок, введіть інший:" << endl;
            fread.get(pat, NumberOfSymbols);
        }
        cout << "Ви считали з файлу:" << endl;
        cout << pat << endl;
    }
    fread.close();
    return pat;
}
void Counter(char* name)
{
    char sym;
    int n = 0;
    ifstream fread(name);
    while (!fread.eof())
    {
        sym=fread.get();
        n++;
    }
    NumberOfSymbols = n;
    fread.close();
}
void Processing(char* txt, char* pat)
{
    cout << "Введіть підрядок для пошуку -> ";
    gets_s(pat, NumberOfSymbols);
    while ((strlen(txt) <= strlen(pat) || strlen(pat) == 0))
    {
        cout << "Сталася помилка. Можливо ви не ввели текст або ви ввели текст більший за головний рядок, введіть інший:" << endl;
        gets_s(pat, NumberOfSymbols);
    }
    
    cout << endl << "Обробка успішна:) Можете вивести результат на екран або записати його в файл" << endl << endl;
}
void Output(char* txt, char* pat, int S)
{
    cout << "Заданий текст:" << endl;
    cout << txt << endl << endl;
    cout << "Ви шукаєте -> " << pat << endl << endl;
    if (S>0)
    {
        cout << "Входження знайдено-> " << S << "-й символ" << endl << endl;
    }
    else
        cout << "Входження не знайдено" << endl;
}
void FOutput(char* txt, char* pat, int S)
{
    char* outname = new char[80];
    cout << "Введіть назву файлу (та шлях якщо потрібно) для запису->";
    gets_s(outname, 80);
    ofstream fout(outname);
    if (!fout.is_open())
    {
        cout << "Створити/відкрити файл для запису неможливо" << endl;
        system("pause");
    }
    else
    {
        fout << "Заданий головний рядок:" << endl << txt << endl << endl << "Ви шукали->" << pat << endl;
        if (S <= 0)
        {
            fout << "Входження не знайдено" << endl;
        }
        else
        {
            fout << "Входження знайдено-> " << S << "-й символ" << endl;
        }
        cout << "Запис в файл " << outname << " успішний :)" << endl;
        fout.close();
    }
    delete[] outname;
}
void BadCharHeuristic(char* str, int size, int* badchar)
{
    int i;
    for ( i = 0; i < 256; i++)
        badchar[i] = -1;
    for ( i = 0; i < size; i++)
        badchar[(int)str[i]] = i;
}

int Search(char* txt, char* pat)  
{
    int n = strlen(txt);
    int m = strlen(pat);
    int badchar[256];
    BadCharHeuristic(pat, m, badchar);
     int count = 0;
     int s = 0;
    while (count <= (n - m))
    {
        int j = m - 1;
        while (j >= 0 && pat[j] == txt[count + j])
            j--;
        if (j < 0)
        {
            return count;
        }
        else  {
            count += max(1, j - badchar[txt[count + j]]);
        }
    }
}
int Max(int a, int b) 
{
    return (a > b) ? a : b;
}
Answer 1

Думаю, что у вас в вашей системе знаковый char, так что такие конструкции

 badchar[(int)str[i]] = i;

выкидывают вас в отрицательные индексы. Попробуйте что-то вроде

 badchar[(unsigned char)str[i]]

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

READ ALSO
Как настроить определение языка сайта?

Как настроить определение языка сайта?

Я нашла вот такой кодНо не понимаю, как реализовать для моего варианта

220
Как передать значения формы ajax запросом в php?

Как передать значения формы ajax запросом в php?

Не получается передать значения формы в php файлphp файл лежит в папке "/php/send

219
TokenMismatchException in compiled.php line 3314:

TokenMismatchException in compiled.php line 3314:

Добрый день возникла данная ошибка после ввода данных в поле на странице регистрации, вот ошибка https://istack

231
Как работает в данном случае str_replace php?

Как работает в данном случае str_replace php?

Как то давно я делал многоязычность c помощью phpИ когда очередь дошла до кнопок переключалок языка, мне посоветовали следующий код:

271