Можно ли хранить только символы n-1 в конце буфера? - PullRequest
0 голосов
/ 13 июля 2020

Можно ли сохранить последние n-1 символов буфера, а затем добавить их в начало нового буфера? Например, если я читаю данные из файла и сохраняю их в буфере размером 1000, возможно ли просто иметь последние n-1 символов текущего буфера и перенести их в начало нового буфера, который идет чтобы прочитать следующие 1000 символов. Я не хочу перечитывать данные из файла. Просто сохраните несколько символов из старого буфера и поместите их в начало нового буфера.

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main(){
    FILE *fptr;
    int l,count=0,index;
    char name[100],word[25],buffer[1000],*pos;
    printf("\nEnter the word to be found:");
    scanf("%s",word);
    l=strlen(word);
    printf("\nEnter the file name:");
    scanf("%s",name);
    fptr=fopen(name,"r");
    if(fptr==NULL){
        printf("\nProblem with opening the file");
        exit(1);
    }
    while ((fgets(buffer, 1000, fptr)) != NULL)
    {
        index = 0;
        while ((pos = strstr(buffer + index, word)) != NULL)
        {
            index = (pos - buffer) + 1;
            count++;
        }
    }
    printf("The word %s is found %d times",word,count);
    fclose(fptr);
}

1 Ответ

1 голос
/ 13 июля 2020

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

Если ваш текущий буфер содержит часть слова, вы можете просто скопировать это «половинное» слово в начало буфера, а в следующем fread указать другой указатель и другую длину.

Что-то вроде:

#define BUF_SZ 1000

char buffer[BUF_SZ];

// Full file read
fread(buffer, 1, BUF_SZ, fp);

// do some stuff
. . .

numbers_in_half_word = 3; // Just as example. In the real code you need
                          // to calculate it based on the first input

// Copy to start of buffer
memcpy(buffer, buffer + (BUF_SZ - numbers_in_half_word), numbers_in_half_word);

// Reduced file read, i.e. max 997 chars - note: ptr moved by 3, length reduced by 3
fread(buffer + numbers_in_half_word, 1, BUF_SZ - numbers_in_half_word, fp);

EDIT

OP только что опубликовал код, показывающий, что было использовано fgets. Принцип все тот же:

int numbers_in_half_word = 0;  // No half-word the first time. So init to zero

while ((fgets(buffer + numbers_in_half_word, 1000 - numbers_in_half_word, fptr)) != NULL)
{

   // do stuff including calculation of the new numbers_in_half_word value

   if (numbers_in_half_word)
   {
       memcpy(buffer, buffer + (1000 - 1 - numbers_in_half_word), numbers_in_half_word);
   }
}

Обратите внимание на -1 в memcpy. Это необходимо, потому что fgets использует buffer[999] в качестве завершения нуля.

Особые соображения

Если полуслова (иначе numbers_in_half_word) равно 500 или больше, чем memmove лучше, чем memcpy

Если полуслова (иначе numbers_in_half_word) - 999, приведенный выше код превратит go в бесконечный l oop, поскольку нет места для новые символы из файла.

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

...