我正在写一篇关于C程序的帮助。目标是查找子文件在文件中出现的次数。用户输入子字符串和文件名。有区分大小写,如果字符串是“the”,它只计算“the”在文件中的次数,而不是“THE”或“The”。文件的每一行不得超过250个字符。我们必须使用strcmp和fgets,不允许使用strstr。
这是我到目前为止的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINELENGTH 250
#define STRINGLENGTH 100
int main ()
{
int count = 0;
FILE *stringFilePtr = NULL;
char *filename[30];
char line[LINELENGTH];
char string[STRINGLENGTH];
int length = STRINGLENGTH;
printf ("Enter the string you want to search for:\n");
fgets (string, STRINGLENGTH, stdin);
printf ("Enter the name of the file you want to search through:\n");
scanf ("%s", filename);
stringFilePtr = fopen (filename, "r");
if (stringFilePtr != NULL) {
while (fgets (line, length, stringFilePtr) != NULL) {
if (strcmp (line, string) == 0);
{
++count;
}
}
fclose (stringFilePtr);
}
else {
printf ("The file %s was unable to open.", filename);
}
printf
("There were %d occurrences of the string %s within the file %s.\n",
count, string, filename);
return 0;
}
答案 0 :(得分:0)
您的代码中存在许多可能会让您感到惊讶的潜在陷阱。您可以在string
之前提示filename
来避免使用'\n'
,但如果相反,您可以在输入缓冲区中留下stdin
(例如{{1}您对fgets
的下一次调用很乐意接受空行。在scanf
函数族和fgets
之间混合输入时,必须始终考虑输入缓冲区中剩余的任何字符。 (您可以在一个简单的循环中执行此操作,并仔细选择格式字符串(例如" %[^\n]%*c"
)。
接下来,虽然STRINGLENGTH
的{{1}}完全取决于您,但值得注意的是,完整词典中最长的单词100
长27-characters
28-chars
适用于任何已知定义的单词。
在阅读文件时,为什么要一次比较一个单词,为什么一次读一行? fscanf
会很乐意在整个文件中逐个读取每个单词,并且在阅读下一个单词之前会跳过任何空白(例如'\n'
),即使它从下一行开始。这也可以帮助您避免在进行搜索字词比较之前检查并删除所有'\n'
s。 (如何从行末删除'\n'
的示例显示在下方string
)
接下来,总是验证所有用户输入,文件打开和内存分配。考虑到这一点,看起来你正在尝试类似于以下的东西,例如
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRINGLENGTH 28 /* longest word in unabridged dictionary is 27-chars */
#ifndef _POSIX_PATH_MAX
#define _POSIX_PATH_MAX 4096
#endif
#define PATH_MAX _POSIX_PATH_MAX
int main (void)
{
int count = 0;
char filename[PATH_MAX] = "",
word[STRINGLENGTH] = "",
string[STRINGLENGTH] = "";
size_t len = 0;
FILE *stringFilePtr = NULL;
printf ("Enter filename: "); /* validate ALL input */
if (scanf ("%s", filename) != 1) {
fprintf (stderr, "error: invalid input - filename.\n");
return 1;
}
/* empty any chars (e.g. '\n') that remain in stdin */
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
/* open & validate file open for reading */
if (!(stringFilePtr = fopen (filename, "r"))) {
fprintf (stderr, "error: file open failed '%s'\n.", filename);
return 1;
}
printf ("Enter search string: ");
if (!fgets (string, STRINGLENGTH, stdin)) {
fprintf (stderr, "error: invalid input\n.");
return 1;
}
len = strlen (string); /* get string length */
if (string[len - 1] == '\n') /* check for trailing '\n' */
string[--len] = 0; /* overwrite with nul-byte */
while (fscanf (stringFilePtr, " %s", word) == 1)
if (strcmp (word, string) == 0)
++count;
fclose (stringFilePtr);
printf ("There are '%d' occurrences of '%s' within file '%s'.\n",
count, string, filename);
return 0;
}
示例输入文件
$ cat ../dat/damages.txt
Personal injury damage awards are unliquidated
and are not capable of certain measurement; thus, the
jury has broad discretion in assessing the amount of
damages in a personal injury case. Yet, at the same
time, a factual sufficiency review insures that the
evidence supports the jury's award; and, although
difficult, the law requires appellate courts to conduct
factual sufficiency reviews on damage awards in
personal injury cases. Thus, while a jury has latitude in
assessing intangible damages in personal injury cases,
a jury's damage award does not escape the scrutiny of
appellate review.
Because Texas law applies no physical manifestation
rule to restrict wrongful death recoveries, a
trial court in a death case is prudent when it chooses
to submit the issues of mental anguish and loss of
society and companionship. While there is a
presumption of mental anguish for the wrongful death
beneficiary, the Texas Supreme Court has not indicated
that reviewing courts should presume that the mental
anguish is sufficient to support a large award. Testimony
that proves the beneficiary suffered severe mental
anguish or severe grief should be a significant and
sometimes determining factor in a factual sufficiency
analysis of large non-pecuniary damage awards.
示例使用/输出
$ ./bin/srchinfile
Enter filename: ../dat/damages.txt
Enter search string: the
There are '12' occurrences of 'the' within file '../dat/damages.txt'.
仔细看看,如果您有任何其他问题,请告诉我。