[英]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.