C 字符串和文件
我正在写一个C程序,需要帮助。目标是查找子字符串在文件中出现的次数。用户输入子字符串和文件名。有区分大小写的功能,如果字符串是“the”,则只计算“the”在文件中的次数,而不是“the”或“the”。文件的每行长度不超过250个字符。我们必须使用strcmp和fgets,不允许使用strstr 以下是我目前掌握的代码:C 字符串和文件,c,string,file,C,String,File,我正在写一个C程序,需要帮助。目标是查找子字符串在文件中出现的次数。用户输入子字符串和文件名。有区分大小写的功能,如果字符串是“the”,则只计算“the”在文件中的次数,而不是“the”或“the”。文件的每行长度不超过250个字符。我们必须使用strcmp和fgets,不允许使用strstr 以下是我目前掌握的代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #define LI
#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;
}
#包括
#包括
#包括
#定义线宽250
#定义STRINGLENGTH 100
int main()
{
整数计数=0;
FILE*stringFilePtr=NULL;
字符*文件名[30];
字符行[行长度];
字符字符串[字符串长度];
int-length=STRINGLENGTH;
printf(“输入要搜索的字符串:\n”);
fgets(字符串、字符串长度、标准输入);
printf(“输入要搜索的文件名:\n”);
scanf(“%s”,文件名);
stringFilePtr=fopen(文件名,“r”);
if(stringFilePtr!=NULL){
while(fgets(行、长度、stringFilePtr)!=NULL){
if(strcmp(行、字符串)==0);
{
++计数;
}
}
fclose(stringFilePtr);
}
否则{
printf(“文件%s无法打开。”,文件名);
}
printf
(“字符串%s在文件%s中出现了%d次。\n”,
计数、字符串、文件名);
返回0;
}
您的代码中有许多潜在的陷阱,可能会让您大吃一惊。通过在文件名
之前提示输入字符串
,可以避免出现这种情况,但是如果相反,则会在输入缓冲区中留下一个'\n'
(例如stdin
),下次调用fgets
时会很乐意将其作为空行接受。在scanf
函数系列和fgets
之间混合输入时,必须始终考虑输入缓冲区中剩余的任何字符。(您可以在一个简单的循环中执行此操作,也可以仔细选择格式字符串(例如,“%[^\n]%*c”
)
接下来,虽然100
的STRINGLENGTH
完全由您决定,但值得注意的是,未桥接词典中最长的单词是27个字符
长,使得28个字符
足以容纳任何已知定义的单词
在读取文件时,如果您想一次比较一个单词,为什么要一行一行地读取呢?fscanf
将愉快地在整个文件中逐个读取每个单词,并跳过任何空白(例如'\n'
)在阅读下一个单词之前,即使它从下一行开始。这也将帮助您避免在进行搜索词比较之前检查并删除所有'\n'
。(如何从行尾删除'\n'
的示例显示在字符串中)
接下来,始终验证所有用户输入、文件打开和内存分配
#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;
}
示例使用/输出
$ ./bin/srchinfile
Enter filename: ../dat/damages.txt
Enter search string: the
There are '12' occurrences of 'the' within file '../dat/damages.txt'.
请仔细检查,如果您还有任何问题,请告诉我。您的问题是什么?1)line
包括换行符。2) 计数
未初始化。3) fclose(stringFilePtr)代码>从else块移到if块。4) 可能行
需要用空格等分隔。如果字符串在同一行上多次出现,则不需要处理这种情况。您会发现strstrstr
对于开始有用,您需要在开始时将count设置为0
$ ./bin/srchinfile
Enter filename: ../dat/damages.txt
Enter search string: the
There are '12' occurrences of 'the' within file '../dat/damages.txt'.