【问题标题】:Is it possible to store only the n-1 characters at the end of a buffer?是否可以仅在缓冲区末尾存储 n-1 个字符?
【发布时间】:2020-07-13 17:39:21
【问题描述】:

是否可以存储缓冲区的最后 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);
}

【问题讨论】:

标签: c file-io buffer


【解决方案1】:

您是正确的 - 如果您正在计算特定单词的出现次数并小部分读取文件,则需要注意并处理只有单词的初始部分位于缓冲区末尾的情况。

如果您当前的缓冲区包含一个单词的一部分,那么您只需将该“半”字复制到缓冲区的开头,然后在下一个 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);

编辑

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);
   }
}

注意 memcpy 中的 -1。这是必需的,因为fgets 使用buffer[999] 作为零终止。

特殊注意事项

如果半字(又名 numbers_in_half_word)是 500 或更多,则 memmove 优于 memcpy

如果半字(又名numbers_in_half_word)是 999,则上面的代码将进入无限循环,因为文件中没有新字符的空间。

一个好的程序应该能够处理这种情况,即使它们不太可能出现在一个单词文件中。

【讨论】:

  • by number_in_half_word,你的意思是要搜索的单词与字符串匹配的字符数,对吧?
  • @SharonShelton 假设您正在寻找“世界”并且您的缓冲区是“很多单词......你好 wor”您需要将最后 3 个字母(即“wor”)复制到缓冲区启动,然后执行下一个fgets
猜你喜欢
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2010-10-13
  • 1970-01-01
  • 2012-06-21
相关资源
最近更新 更多