字符串和文件

时间:2017-04-13 22:16:49

标签: c string file

我正在写一篇关于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;
}

1 个答案:

答案 0 :(得分:0)

您的代码中存在许多可能会让您感到惊讶的潜在陷阱。您可以在string之前提示filename来避免使用'\n',但如果相反,您可以在输入缓冲区中留下stdin (例如{{1}您对fgets的下一次调用很乐意接受空行。在scanf函数族和fgets之间混合输入时,必须始终考虑输入缓冲区中剩余的任何字符。 (您可以在一个简单的循环中执行此操作,并仔细选择格式字符串(例如" %[^\n]%*c")。

接下来,虽然STRINGLENGTH的{​​{1}}完全取决于您,但值得注意的是,完整词典中最长的单词10027-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'.

仔细看看,如果您有任何其他问题,请告诉我。