Вопрос про строки в Си
Есть двоичный файл и в нём есть текст а после любое число, или даже ноль.
Размер слова в файле не известен.
Но я ищу определённое слово.
Кусок файла
01 4C 61 6E 63 65 72 02
Пусть это будет слово Lancer. После слова идут данные. Нет гарантии что это Lancer.
Я читаю буфер, подхожу к первому символу слова,
uint8_t buf[256];
memset(buf, 0, 256);
fread(...);
if(buf[0] == 1) // например пусть вначале всегда 1
{
if(buf[1] == 'L')
{
// Как теперь проверить что символы начиная с buf[1]
// совпадут с "Lancer"?
}
else if(buf[1] == 'P') // А ещё может быть другое слово
{
}
}
else
{
ошибка
}
Алгоритм примерно такой:
Вычисляем длину слова в байтах (это будет размер окна) и циклическую сумму байт слова по модулю 256 (т.е. если у нас sum = 255 то sum + 2 = 1 а не 257)
Вычисляем циклическую сумму байт из файла, равную размеру окна из пункта 1.
Если сумма байт совпадает с суммой байт окна ТО выполняем memcmp, чтобы удостоверится, что слово и содержимое окна совпадают
Если сумма байт НЕ совпадает с суммой байт окна ТО сдвигаем окно на 1 байт вправо. Для этого отнимаем от ранее вычисленной суммы значение самого левого байта в окне и прибавляем значение байта, расположенного сразу справа от окна и переходим к пункту 3
Подобный подход позволит быстро выполнять сравнение больших последовательностей, и чем больше дубет длина искомой последовательности байт (слова) тем больше будет выигрыш по скорости перед тупым сдвигом memcmp по буферу с данными.
```c
#include <stdint.h>
#include <stdio.h>
#include <string.h>
uint8_t buf[256];
memset(buf, 0, 256);
fread(buf, 1, 256, file); // Замените file на ваш файл
if (buf[0] == 1) // например пусть вначале всегда 1
{
if (memcmp(&buf[1], "Lancer", 6) == 0)
{
// Символы совпадают с "Lancer"
}
else if (memcmp(&buf[1], "P", 1) == 0) // А ещё может быть другое слово
{
// Символы совпадают с "P"
}
}
else
{
// ошибка
}
```
Функция `memcmp` сравнивает первые `n` байт двух блоков памяти. В данном случае `&buf[1]` - это указатель на второй байт буфера (где начинается слово), `"Lancer"` - строка, с которой мы сравниваем, и `6` - длина строки "Lancer". Если первые 6 байт в `buf` начиная с `buf[1]` совпадают с "Lancer", `memcmp` вернет `0`.
Этот подход можно использовать и для других слов, изменяя строку и длину для сравнения.
заводите счетчик символов искомого слова (например cnt) изначально = 0
считываете символ из файла
сравниваете его с символом слова на которое указывает cnt
при сравнении увеличиваете cnt на еденичку,
таким образом следующий символ из файла будет сравниваться со следующим символом слова.
проверяете если word[cnt] == 0 значит слово было найдено
если самое первое сравнение неудачно то cnt сбрасываем на ноль, чтобы снова искать первую букву.
while (symbol = getc(file), symbol != EOF) //считываем символ
{
if ((char)symbol == word[cnt])
{
cnt++;
if (word[cnt]==0)
{
//ТАДА! слово найдено
//и с этим нужно что-то делать
}
}
else cnt = 0;
}