Поиск комбинации в массиве и ее инверсия
Помогите доработать программу , не получается с поиском комбинации и ее инверсией.
Задание:
Исходные данные: файл, созданный в текстовом редакторе содержащий текст, длина которого не превышает 128 символов. Требуется разработать алгоритм и написать программу, позволяющую:: • выводить данные из файла в битовом виде на экран дисплея; • с помощью отдельной функции осуществлять поиск введенной пользователем двоичной комбинации и ее замену на инверсную ей комбинацию; • выводить результат на экран и сохранять в файл.
#include <iostream>
#include <fstream>
using namespace std;
void charToBit(char mass[]);
int look(int massBit[]);
void read()
{
string path = "file.txt";
cout << "Введите название файла \n";
//cin >> path;
ifstream obj;
obj.open(path);
if (!obj.is_open())
{
cout << "Ошибка открытия файла\n";
}
else
{
cout << "Файл открыт \n";
char mass[140];
while (!obj.eof())
{
obj.getline(mass,140);
cout << mass;
}
cout << endl;
obj.close();
charToBit(mass);
}
}
void charToBit(char mass[])
{
int massBit[1024];
for (int s = 0, j = 7, k = 0; k < 1024; k++, j--)
{
if (j == 0)
{
s++;
j = 7;
}
massBit[k] = mass[s] >> j & 1;
if (k % 70 == 0)
cout << endl;
cout << massBit[k];
}
cout << endl;
//look(massBit);
if (look(massBit) == true)
cout << "yes\n";
else
cout << "no\n";
}
int look(int massBit[])
{
const int count = 1024;
int l = 0; // нижняя граница
int u = count-1 ; // верхняя граница
int key[6];
cout << "\nВведите комбинацию \n";
for(int i=0;i<6;i++)
cin >> key[i];
while (l <= u)
{
int m = (l + u) ;
if (massBit[m] == key[l])
{
return true;
}
if (massBit[m] < key[l])
{
l = m + 1;
return false;
}
if (massBit[m] > key[l])
{
u = m - 1;
return false;
}
}
return 0;
}
int main()
{
setlocale(LC_ALL, "ru");
read();
}
Ответы (1 шт):
Вот код почти полного решения. Только я вывожу конвертированный текст в консоль, а не в файл, но с этим проблем быть не должно. Ну и имя файла читаю из аргумента командной строки, а не из консоли. Возможно решение покажется сложным, попробуйте разобраться. Если что пишите в комментариях, отвечу.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
void charsToBits(char mass[]);
int look(const char *massBit);
char *my_strnstr(const char *big, const char *little, size_t len)
{
size_t lenlit;
size_t lenbig;
size_t i;
char *tmp;
lenlit = strlen((char*)little);
if (!lenlit)
return ((char*)big);
lenbig = strlen((char*)big);
while (len-- >= lenlit && lenbig-- >= lenlit)
{
i = 0;
tmp = (char*)little;
while (*tmp && *tmp++ == *(char*)(big + i))
i++;
if (i == lenlit)
{
return ((char *)big);
}
big++;
}
return (NULL);
}
void charArrToBitArr(const char *src, char *dest) {
while (*src) {
for (int i = 7; i >= 0; --i) {
*dest = (*src & (1 << i)) ? '1' : '0';
++dest;
}
++src;
}
}
void read(char *file)
{
ifstream obj;
obj.open(file);
if (!obj.is_open()) {
cout << "Ошибка открытия файла\n";
}
else {
cout << "Файл открыт \n";
char mass[129] = {0};
obj.getline(mass,128);
cout << mass << endl;
obj.close();
charsToBits(mass);
}
}
void charsToBits(char *mass)
{
char bits[1025] = {0};
charArrToBitArr(mass, bits);
cout << bits << endl;
if (look(bits))
cout << "yes\n";
else
cout << "no\n";
}
int look(const char *bits)
{
char key[1025];
cout << "Введите комбинацию:" << endl;
cin >> key;
key[1024] = 0;
char *subSrtStart = my_strnstr(bits, key, strlen(bits));
if (!subSrtStart)
return 0;
for (size_t i = 0; i < strlen(key); ++i) {
subSrtStart[i] = subSrtStart[i] == '1' ? '0' : '1';
}
cout << bits << endl;
return 1;
}
int main(int argc, char **argv)
{
(void)argc;
setlocale(LC_ALL, "ru");
read(argv[1]);
}
UPD Изменил текст программы, в связи с замечанием @avp. Программа теперь ищет вхождение последовательности длинной до 1024 символов включительно. Находит только первое вхождение, если нужно найти все вхождения, то нужно strnstr вызывать в цикле со смещением строки-источника.
strnstr самописная, если не запрещено заданием (в чём я сомневаюсь), то можно её заменить на какую-то библиотечную функцию.