我是编程新手,所以请友好一点。
目前,我正在尝试编写一个程序,打开一个文本文件,读取两个单词,在文本文件中搜索,计算两个单词出现的次数,然后最后打印第一个单词出现的第一行。
到目前为止,我所做的是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *infile;
char inputWord1[100], inputWord2[100], filename[100], wordInText[100], line[500];
int i, count, strComp, word1Count, word2Count, wordLen, lineCount;
char c;
int main() {
printf("Enter the first word: ");
gets(inputWord1);
printf("Enter the second word: ");
gets(inputWord2);
printf("Enter the file name: ");
gets(filename);
infile = fopen(filename, "r");
if(infile == NULL) {
printf("Error");
exit(1);
}
word1Count = 0; word2Count = 0; lineCount = 1;
while(fscanf(infile, "%s", wordInText) != EOF) {
wordLen = strlen(wordInText);
for(i = 0; i < wordLen; i++) {
if(wordInText[i] >= 65 && wordInText[i] <= 90) {
wordInText[i] = wordInText[i] + 32;
}
}
for(c = getc(infile); c != EOF; c = getc(infile)) {
if(c == 'n') {
lineCount = lineCount + 1;
}
}
strComp = strcmp(wordInText, inputWord1);
if(strComp == 0) {
word1Count++;
if(word1Count == 1) {
for(int x = lineCount; x <= lineCount; x++) {
fgets(line, 500, infile);
printf("%sn", line);
}
}
}
strComp = strcmp(wordInText, inputWord2);
if(strComp == 0) {
word2Count++;
}
}
printf("Word 1 appears %d timesn", word1Count);
printf("Word 2 appears %d timesn", word2Count);
}
这些都可以,除了:
strComp = strcmp(wordInText, inputWord1);
if(strComp == 0) {
word1Count++;
if(word1Count == 1) {
for(int x = lineCount; x <= lineCount; x++) {
fgets(line, 500, infile);
printf("%sn", line);
}
}
}
最后一个for循环没有正常工作。它输出n,但不打印行。我真的不知道为什么不行。其他部分都很好。
如果有人有任何关于如何解决这个问题的想法,我将非常感激。请记住,我只知道基本的C函数,我还没有完全完成这个程序(还需要将输入的单词转换为小写)。
get应该被替换以避免缓冲区溢出我使用了一些定义,当我们找到单词时,输入行是dup并在末尾打印。文件被逐行读取,每行被逐字分割。解析应该更新,例如允许多个空格,支持更多的分隔符等…
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define WORD_LEN_MAX 100
#define LINE_LEN_MAX 500
int main() {
FILE *infile;
char inputWord1[WORD_LEN_MAX], inputWord2[WORD_LEN_MAX];
char filename[WORD_LEN_MAX];
char wordInText[WORD_LEN_MAX], line[LINE_LEN_MAX];
char firsAppear[LINE_LEN_MAX];
int word1Count, word2Count, lineCount, i;
printf("Enter the first word: ");
gets(inputWord1);
printf("Enter the second word: ");
gets(inputWord2);
printf("Enter the file name: ");
gets(filename);
infile = fopen(filename, "r");
if(infile == NULL) {
printf("Error cannot open %s", filename);
exit(1);
}
word1Count = 0; word2Count = 0; lineCount = 1;
while(fgets(line, sizeof(line), infile) != NULL) {
char *p = line;
lineCount++;
while (*p != ' ' && *p != 'n') {
i = 0;
while (*p != ' ' && *p != ' ' && *p != 'n') {
wordInText[i++] = tolower(*p++);
}
if (*p == ' ') {
p++;
}
wordInText[i] = ' ';
if(!strcmp(wordInText, inputWord1)) {
word1Count++;
if(word1Count == 1) {
strncpy(firsAppear, line, sizeof(firsAppear));
}
}
if(!strcmp(wordInText, inputWord2)) {
word2Count++;
}
}
}
printf("Word 1 appears %d timesn", word1Count);
printf("Word 2 appears %d timesn", word2Count);
printf("%s", firsAppear);
}
有很多方法可以做到这一点。然而,你所选择的方法必须是更困难的一端。在寻找要使用的正确工具时,当读取行时,使用面向行的输入几乎总是正确的选择。因此,gets
绝不是的正确选择。它是非常不安全的,已经从C库中删除,使用fgets
代替(或getline
)。
当你需要比较单词并计算匹配次数时,就这样做…比较它们,如果匹配则加和。
对于lineCount
,如果您使用面向行的输入,则很简单,只需为每一行读取增加计数器。
但是如何得到测试的单词呢?strtok
(或strsep
)是提供的工具。只需读取一行并对进行标记。然后比较和递增。
newline
)。它很简单,读取一行,标记,比较和增加匹配,增加lineCount。完成:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Avoid Globals */
#define MAXL 500
#define MAXW 100
int main (void)
{
char inputWord1[MAXW] = { 0 }; /* Always Initialize your Variables */
char inputWord2[MAXW] = { 0 };
char filename[MAXW] = { 0 };
char line[MAXL] = { 0 };
char *token = NULL;
char *delim = " ,.;n";
size_t word1Count = 0; /* can't be negative, use */
size_t word2Count = 0; /* size_t or unsigned */
size_t lineCount = 0;
size_t len = 0;
FILE *infile = NULL;
printf ("nEnter the first word: "); /* Do NOT use gets, it is insecure */
fgets (inputWord1, MAXW, stdin); /* use fgets or getline instead */
len = strlen (inputWord1);
while (len > 0 && (inputWord1[len-1] == 'n' || inputWord1[len-1] == 'r'))
inputWord1[--len] = 0; /* strip newline or carriage return */
printf ("nEnter the second word: ");
fgets (inputWord2, MAXW, stdin);
len = strlen (inputWord2);
while (len > 0 && (inputWord2[len-1] == 'n' || inputWord2[len-1] == 'r'))
inputWord2[--len] = 0; /* strip newline or carriage return */
printf ("nEnter the file name: ");
fgets (filename, MAXW, stdin);
len = strlen (filename);
while (len > 0 && (filename[len-1] == 'n' || filename[len-1] == 'r'))
filename[--len] = 0; /* strip newline or carriage return */
infile = fopen (filename, "r");
if (infile == NULL) {
printf ("error: file open failed. '%s'n", filename);
exit (1);
}
printf ("nThe lines processed are:nn");
/* read each line, tokenize, compare and increment */
while (fgets (line, MAXL, infile) != NULL)
{
len = strlen (line);
while (len > 0 && (line[len-1] == 'n' || line[len-1] == 'r'))
line[--len] = 0; /* strip newline or carriage return */
printf (" %2zu %sn", lineCount, line);
for (token = strtok (line, delim); token != NULL; token = strtok (NULL, delim))
{
if (strcmp (token, inputWord1) == 0)
word1Count++;
if (strcmp (token, inputWord2) == 0)
word2Count++;
}
lineCount++;
}
printf ("nWord 1 appears %zu timesn", word1Count);
printf ("Word 2 appears %zu timesn", word2Count);
printf ("Number of lines: %zunn", lineCount);
return 0;
}
使用/输出
$ ./bin/countw1w2
Enter the first word: me
Enter the second word: chequer
Enter the file name: dat/ll_replace_poem.txt
The lines processed are:
0 Eye have a spelling chequer,
1 It came with my Pea Sea.
2 It plane lee marks four my revue,
3 Miss Steaks I can knot sea.
4 Eye strike the quays and type a whirred,
5 And weight four it two say,
6 Weather eye am write oar wrong,
7 It tells me straight aweigh.
8 Eye ran this poem threw it,
9 Your shore real glad two no.
10 Its vary polished in its weigh.
11 My chequer tolled me sew.
12 A chequer is a bless thing,
13 It freeze yew lodes of thyme.
14 It helps me right all stiles of righting,
15 And aides me when eye rime.
16 Each frays come posed up on my screen,
17 Eye trussed too bee a joule.
18 The chequer pours over every word,
19 Two cheque sum spelling rule.
Word 1 appears 4 times
Word 2 appears 4 times
Number of lines: 20