Top.Mail.Ru
Ответы

Вопрос про строки в Си

Есть двоичный файл и в нём есть текст а после любое число, или даже ноль.
Размер слова в файле не известен.
Но я ищу определённое слово.

Кусок файла

1
 01 4C 61 6E 63 65 72 02 

Пусть это будет слово Lancer. После слова идут данные. Нет гарантии что это Lancer.

Я читаю буфер, подхожу к первому символу слова,

1234567891011121314151617181920
 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
{
ошибка
} 
По дате
По Рейтингу
Аватар пользователя
Новичок
11мес

Алгоритм примерно такой:

  1. Вычисляем длину слова в байтах (это будет размер окна) и циклическую сумму байт слова по модулю 256 (т.е. если у нас sum = 255 то sum + 2 = 1 а не 257)

  2. Вычисляем циклическую сумму байт из файла, равную размеру окна из пункта 1.

  3. Если сумма байт совпадает с суммой байт окна ТО выполняем memcmp, чтобы удостоверится, что слово и содержимое окна совпадают

  4. Если сумма байт НЕ совпадает с суммой байт окна ТО сдвигаем окно на 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 сбрасываем на ноль, чтобы снова искать первую букву.

12345678910111213
 	while (symbol = getc(file), symbol != EOF) //считываем символ 
	{ 
		if ((char)symbol == word[cnt])  
		{ 
			cnt++; 
			if (word[cnt]==0)  
			{ 
				//ТАДА! слово найдено
				//и с этим нужно что-то делать
			} 
		} 
		else cnt = 0; 
	}