Как перечитать несколько символов с конца буфера в C? - PullRequest
0 голосов
/ 09 июля 2020

Я использую буфер для временного хранения определенных байтов данных (символов) из файла. Я просто хочу узнать, присутствует ли в файле определенное слово. Скажем, я ищу слово «Apple» и сохраняю строку из файла в буфер, который имеет первую половину «App» в конце буфера и «le» в следующем буфере. Я просто хочу убедиться, что эти слова не пропущены. Что я могу сделать, чтобы перечитать определенную длину в конце буфера. Как я могу изменить следующий код?

while(feof(fptr)==0){
    char * result;
    char line[100];
    result = fgets( line, sizeof( line ), fptr );

    if ( result == NULL ){
        break;
    }

    line[strcspn( line, "\n" ) ] = '\0';
    token = strtok(line," \t,:;\'\"\?!-_|\\><~@#$%^&*()+{}[].=1234567890");

    while( token != NULL ) {
        printf( " %s\n", token );
        if(strcasecmp(token,word)==0){
            count++; //counts the number of occurrence of the word 
        }
        token = strtok(NULL," \t,:;\'\"\?!-_|\\><~@#$%^&*()+{}[].=1234567890");
    }
}

1 Ответ

0 голосов
/ 09 июля 2020

Вы не можете обязательно перечитать данные - если вы читаете из файла, который можете искать, но если вы читаете из канала, вы не можете, и вы хотите, чтобы ваша программа работала с обоими, если возможно.

Однако у вас уже есть эти данные в буфере. Таким образом, вы можете просто использовать копию, которая у вас уже есть, и переместить ее в начало буфера:

char line[100]; // declare this outside the loop since we need to keep using the same variable

// start it off full of spaces: (or any other symbol you aren't searching for)
memset(line, ' ', 99);
line[99] = '\0';

В l oop:

// Let's say you're looking for 5 letters ("Apple") so you want a 5-letter overlap.
// Note: we know the buffer has at least 5 valid letters in it, because we always keep that many in it.
memmove(line, line + strlen(line) - 5, 5);
result = fgets( line + 5, sizeof( line ) - 5, fptr );

Что мы делаем ?

Мы берем конец предыдущего буфера и перемещаем его обратно в начало, затем считываем дополнительные данные, чтобы заполнить остальную часть буфера.


Input data: "hello world this is a testerino and here's some more text\n" and we've already read some of it.

Before memmove:
+---------------------------------------------+
|hello world this is a testerino\0djflhashdasa| <- line (the part after the \0 could be gibberish)
+---------------------------------------------+
                           ^^^^^ what we are copying
After memmove:
+---------------------------------------------+
|erino world this is a testerino\0djflhashdasa| <- line
+---------------------------------------------+
 ^^^^^ where we copy it to

After fgets:
+---------------------------------------------+
|erino and here's more text\n\0no\0djlhashdasa| <- line
+---------------------------------------------+
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ what we ask fgets to read
      ^^^^^^^^^^^^^^^^^^^^^^^^^ what it actually read

And repeat

(примечание: \ n и \ 0 на самом деле не занимают два байта, я просто показываю их в целях иллюстрации)

Примечание: это не решает проблему полностью! Если вы ищете «Apple» и читаете «crabApple», а буфер заканчивается сразу после «Apple», вы переместите «Apple» обратно в начало, а затем определите его как слово. Кроме того, если вы читаете «Apple», а затем буфер заканчивается, вы можете обнаружить его дважды (перед перемещением и после перемещения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...