[英]How would I compare a string (entered by the user) to the first word of a line in a file?
我真的很难理解字符数组如何在C中工作。这看起来应该很简单,但是我不知道要使用什么函数,或者如何使用它。
我希望用户输入一个字符串,并且要遍历文本文件,将该字符串与文件中每行的第一个单词进行比较。
这里的“单词”是指由非空格字符组成的子字符串。
非常感谢您的帮助!
编辑:更清楚地说,我想输入一个并在文本文件形式的数据库中搜索它。 我知道如果它在数据库中,它将是一行的第一个字,因为这是如何格式化数据库的。 我想我可以遍历数据库的每个单词,但这似乎效率较低。
在数据库中找到输入之后,我需要访问它之后的两个单词(在同一行上)以实现程序的最终目标(本质上是计算性的)
这是一些可以满足您要求的代码。 我认为它将帮助您更好地了解字符串函数的工作方式。 注意-对于输入和文本文件的条件调整情况,我并没有做很多假设,因此有很多代码可以从输入中删除空格,并检查匹配是否确实是“第一个单词”,而不是“第一个单词的第一部分”。 因此,此代码不会将输入“ hello”与“ helloworld 123 234”行匹配,但将与“ helloworld 123 234”行匹配。 还要注意,它目前区分大小写。
#include <stdio.h>
#include <string.h>
int main(void) {
char buf[100]; // declare space for the input string
FILE *fp; // pointer to the text file
char fileBuf[256]; // space to keep a line from the file
int ii, ll;
printf("give a word to check:\n");
fgets(buf, 100, stdin); // fgets prevents you reading in a string longer than buffer
printf("you entered: %s\n", buf); // check we read correctly
// see (for debug) if there are any odd characters:
printf("In hex, that is ");
ll = strlen(buf);
for(ii = 0; ii < ll; ii++) printf("%2X ", buf[ii]);
printf("\n");
// probably see a carriage return - depends on OS. Get rid of it!
// note I could have used the result that ii is strlen(but) but
// that makes the code harder to understand
for(ii = strlen(buf) - 1; ii >=0; ii--) {
if (isspace(buf[ii])) buf[ii]='\0';
}
// open the file:
if((fp=fopen("myFile.txt", "r"))==NULL) {
printf("cannot open file!\n");
return 0;
}
while( fgets(fileBuf, 256, fp) ) { // read in one line at a time until eof
printf("line read: %s", fileBuf); // show we read it correctly
// find whitespace: we need to keep only the first word.
ii = 0;
while(!isspace(fileBuf[ii]) && ii < 255) ii++;
// now compare input string with first word from input file:
if (strlen(buf)==ii && strstr(fileBuf, buf) == fileBuf) {
printf("found a matching line: %s\n", fileBuf);
break;
}
}
// when you get here, fileBuf will contain the line you are interested in
// the second and third word of the line are what you are really after.
}
我认为您需要的是fseek()
。
1)如下处理数据库文件。 找出所有'\\ n'的位置(回车),并将它们存储在数组中,例如a
,以便您知道第i
行从文件开头开始于第a[i]
个字符。
2) fseek()
是stdio.h中的一个库函数,并且按此处给出的方式工作。 因此,当您需要处理输入字符串时,只需从文件的开头开始,然后仅在数组a
存储的位置检查第一个单词。 要做到这一点:
fseek(inFile , a[i] , SEEK_SET);
接着
fscanf(inFile, "%s %s %s", yourFirstWordHere, secondWord, thirdWord);
用于检查第i
行。 或者,更有效地,您可以使用:
fseek ( inFile , a[i]-a[i-1] , SEEK_CURR )
说明:fseek()的作用是,将与文件关联的读写位置指示器设置在所需位置。 因此,如果您知道什么时候需要读或写,则可以直接去那里阅读或直接写。 这样,您无需阅读整行代码就可以获取前三个单词。
您最近的更新表明该文件实际上是一个数据库,您正在其中搜索单词。 这个非常重要。
如果您有足够的内存来容纳整个数据库,则应该执行此操作(读取整个数据库并安排进行有效搜索),因此您可能不应该询问在文件中进行搜索。
好的数据库设计涉及数据结构,例如trie和hash表 。 但是首先,您可以使用数据库的最基本的改进-以字母顺序保留单词(使用有些棘手的qsort函数来实现)。
struct Database
{
size_t count;
struct Entry // not sure about C syntax here; I usually code in C++; sorry
{
char *word;
char *explanation;
} *entries;
};
char *find_explanation_of_word(struct Database* db, char *word)
{
for (size_t i = 0; i < db->count; i++)
{
int result = strcmp(db->entries[i].word, word);
if (result == 0)
return db->entries[i].explanation;
else if (result > 0)
break; // if the database is sorted, this means word is not found
}
return NULL; // not found
}
如果您的数据库太大而无法容纳在内存中,则应使用一个Trie来容纳数据库中单词的开头; 对于单词的每个开头,都有一个文件偏移量,从该位置开始扫描文件。
char* find_explanation_in_file(FILE *f, long offset, char *word)
{
fseek(f, offset, SEEK_SET);
char line[100]; // 100 should be greater than max line in file
while (line, sizeof(line), f)
{
char *word_in_file = strtok(line, " ");
char *explanation = strtok(NULL, "");
int result = strcmp(word_in_file, word);
if (result == 0)
return explanation;
else if (result > 0)
break;
}
return NULL; // not found
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.