在文本文件C中搜索字符串
以下代码一次读取一个文本文件一个字符,然后将其打印到标准输出:在文本文件C中搜索字符串,c,search,string,C,Search,String,以下代码一次读取一个文本文件一个字符,然后将其打印到标准输出: #include <stdio.h> int main() { char file_to_open[] = "text_file.txt", ch; FILE *file_ptr; if((file_ptr = fopen(file_to_open, "r")) != NULL) { while((ch = fgetc(file_ptr)) != EOF)
#include <stdio.h>
int main()
{
char file_to_open[] = "text_file.txt", ch;
FILE *file_ptr;
if((file_ptr = fopen(file_to_open, "r")) != NULL)
{
while((ch = fgetc(file_ptr)) != EOF)
{
putchar(ch);
}
}
else
{
printf("Could not open %s\n", file_to_open);
return 1;
}
return(0);
}
strings.txt
:
1993 - 1999 Pentium
1997 - 1999 Pentium II
1999 - 2003 Pentium III
1998 - 2009 Xeon
2006 - 2009 Intel Core 2
Nehalem
AMD Athlon
Pentium
尼哈勒姆
阿特隆酒店
奔腾
在这种情况下,text_file.txt
的前三行将匹配。我对C语言中的文件操作做了一些研究,似乎我可以用fgetc
[就像我在代码中做的那样]一次读一个字符,用fgets
读一行,用fread
读一个块,但我想在我的情况下没有一个单词是完美的?记住:fgetc(),getc(),getchar都返回一个整数,不是一个字符。整数可能是EOF或有效字符,但它返回的值比字符类型支持的范围多一个值
您正在为“fgrep”命令编写代理:
fgrep -f strings.txt text_file.txt > out.txt
您需要使用fgets()读取行,而不是读取字符。(忘记存在get()函数!)
我缩进了您的代码并插入了一个返回0;在结尾处(尽管如果从main()的结尾处掉下来,C99会隐式返回0;)。然而,C99也要求每个函数都有一个显式的返回类型——我为您在“int main()”中添加了“int”(但您不能用C99兼容的借口在结尾不返回0)。错误消息应该写入标准错误,而不是标准输出
您可能需要对字符串列表使用动态分配。简单的搜索将简单地应用“strstr()”搜索每行输入中的每个所需字符串(确保在找到匹配项后中断循环,以便在一行上有多个匹配项时不会重复该行)
更复杂的搜索将预先计算哪些字符可以忽略,这样您就可以并行搜索所有字符串,跳过文本的速度比循环中的快。这可能是对搜索算法的修改,例如Boyer Moore或Knuth Morris Pratt(添加:或Rabin Karp,其设计用于并行搜索多个字符串)。按块读取总是更好,因为它是底层文件系统的工作方式 因此,只需按块读取,检查缓冲区中是否出现任何单词, 然后读取另一个缓冲区已满。您只需小心地在新缓冲区中重新复制上一个缓冲区的最后几个字符,以避免在搜索词位于缓冲区边界时丢失检测
如果这个简单的算法还不够(在您的情况下,它可能是不够的),那么还有更复杂的算法可以在一个缓冲区中同时搜索多个子字符串cf。我假设这是一个学习练习,您只是在寻找一个开始的地方。否则,你不应该重新发明轮子 下面的代码应该让您了解其中所涉及的内容。它是一个程序,允许您指定要搜索的文件名和要在该文件中搜索的单个参数。您应该能够修改它,将要搜索的短语放入字符串数组中,并检查该数组中的任何单词是否出现在所读取的任何行中 您正在寻找的关键功能是
#包括
#包括
#包括
#ifdef调试
#定义初始分配2
#否则
#定义初始分配512
#恩迪夫
煤焦*
读取行(文件*fin){
字符*缓冲区;
char*tmp;
int read_chars=0;
int bufsize=初始分配;
char*line=malloc(bufsize);
如果(!行){
返回NULL;
}
缓冲区=行;
而(fgets(缓冲区、bufsize-读取字符、fin)){
read_chars=strlen(行);
如果(第[read_chars-1]行='\n'){
行[read_chars-1]='\0';
回流线;
}
否则{
bufsize=2*bufsize;
tmp=realloc(直线,bufsize);
如果(tmp){
直线=tmp;
缓冲区=行+读取字符;
}
否则{
自由线;
返回NULL;
}
}
}
返回NULL;
}
int
main(int argc,char*argv[]){
文件*fin;
字符*行;
如果(argc!=3){
返回退出失败;
}
fin=fopen(argv[1],“r”);
国际单项体育联合会(财务){
而(行=读取行(fin)){
if(strstr(行,argv[2])){
fprintf(标准输出,“%s\n”,行);
}
自由线;
}
}
财务总监(财务);
返回0;
}
样本输出:
E:\Temp> searcher.exe searcher.c char
char *
char *buffer;
char *tmp;
int read_chars = 0;
char *line = malloc(bufsize);
while ( fgets(buffer, bufsize - read_chars, fin) ) {
read_chars = strlen(line);
if ( line[read_chars - 1] == '\n' ) {
line[read_chars - 1] = '\0';
buffer = line + read_chars;
main(int argc, char *argv[]) {
char *line;
E:\Temp>searcher.exe searcher.c char
煤焦*
字符*缓冲区;
char*tmp;
int read_chars=0;
char*line=malloc(bufsize);
而(fgets(缓冲区、bufsize-读取字符、fin)){
read_chars=strlen(行);
如果(第[read_chars-1]行='\n'){
行[read_chars-1]='\0';
缓冲区=行+读取字符;
main(int argc,char*argv[]){
字符*行;
你为什么要写这个程序?!使用grep/awk/sed来做这个。不,Tim。标记是用来搜索的。没有人会去搜索。是的,我知道用标准的Unix工具我可以在几秒钟内解决这个问题,但这是为了更深入地理解C文件IO。当你使用fgetc()时,我相当肯定stdio将按块和缓冲字符读取…是的,但是调用fgetc本身会有成本,如果您想将输入与一个字符串(或多个字符串)进行比较你必须将其复制到某个地方。这比读取完整缓冲区并使用它的成本要高得多。如果你不想管理自己直接读取缓冲区的血淋淋的细节,那么按照Jonathan的建议读取完整行也是读取完整缓冲区的一个好选择。你的意思是
fgrep-f strings.txt text\u file.txt>out.txt代码>?是的,是的,fgrep-f strings.txt text_file.txt
。我想更多的接触意味着更多的选择。谢谢。编写一个C程序来做这件事完全是浪费时间。任何与学习有关的事情都不是浪费时间,至少我认为是这样。但如果这不是为了学习一些东西
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef DEBUG
#define INITIAL_ALLOC 2
#else
#define INITIAL_ALLOC 512
#endif
char *
read_line(FILE *fin) {
char *buffer;
char *tmp;
int read_chars = 0;
int bufsize = INITIAL_ALLOC;
char *line = malloc(bufsize);
if ( !line ) {
return NULL;
}
buffer = line;
while ( fgets(buffer, bufsize - read_chars, fin) ) {
read_chars = strlen(line);
if ( line[read_chars - 1] == '\n' ) {
line[read_chars - 1] = '\0';
return line;
}
else {
bufsize = 2 * bufsize;
tmp = realloc(line, bufsize);
if ( tmp ) {
line = tmp;
buffer = line + read_chars;
}
else {
free(line);
return NULL;
}
}
}
return NULL;
}
int
main(int argc, char *argv[]) {
FILE *fin;
char *line;
if ( argc != 3 ) {
return EXIT_FAILURE;
}
fin = fopen(argv[1], "r");
if ( fin ) {
while ( line = read_line(fin) ) {
if ( strstr(line, argv[2]) ){
fprintf(stdout, "%s\n", line);
}
free(line);
}
}
fclose(fin);
return 0;
}
E:\Temp> searcher.exe searcher.c char
char *
char *buffer;
char *tmp;
int read_chars = 0;
char *line = malloc(bufsize);
while ( fgets(buffer, bufsize - read_chars, fin) ) {
read_chars = strlen(line);
if ( line[read_chars - 1] == '\n' ) {
line[read_chars - 1] = '\0';
buffer = line + read_chars;
main(int argc, char *argv[]) {
char *line;