c - 如何从 C 中的缓冲区末尾重新读取几个字符?
问题描述
我正在使用缓冲区来临时存储文件中的某些字节数据(字符)。我只想找出文件中是否存在特定单词。比方说,我正在搜索一个单词“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");
}
}
解决方案
您不一定可以重新读取数据 - 如果您正在读取您可以查找的文件,但如果您正在从管道读取,那么您不能,并且您希望您的程序在可能的情况下同时使用两者。
但是,您已经在缓冲区中拥有该数据。因此,您可以只使用已有的副本,并将其移动到缓冲区的开头:
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';
在循环:
// 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”然后缓冲区结束,您可能会检测到两次(移动之前和移动之后)。
推荐阅读
- amazon-web-services - Kinesis 数据分析不能将同一流两次用于不同的目的地
- c++ - 在元组中混合左值和右值的可变模板构造函数
- python - 当工作流测试失败时,如何避免在 Github 中推送?
- android-studio - 创建新项目后,Android Studio 3.6.3 中没有任何效果
- javascript - 在反应中更新数组的嵌套对象中的值
- matlab - 关于 MATLAB 中的“imresize”的困惑?
- python - 无法导入 stargazer(“ModuleNotFoundError: No module named 'stargazer')
- python - 选择查询后清除对 postgres 关系的访问共享锁定
- ffmpeg - gStreamer:使用 RAM 分区中的 jpeg 图像创建 RTSP 流
- sql - 如何替换以一组“特殊”字符(标签)开头和结尾的字符串