C 正在读取格式未知的文本文件

C 正在读取格式未知的文本文件,c,regex,file-io,dynamic-memory-allocation,C,Regex,File Io,Dynamic Memory Allocation,我正在尝试从文本文件中读取。此文本文件没有特定的模式,但它是故事的一段。我试图获取每个单词并跟踪它们出现的次数 例如,这是文本文件中的一个练习,用于了解格式 在提交以下记录时,我们意识到我们有错误。其中一些已经被发现并被销毁 即使在模板已经出来之后,也要用钢笔更正。其他的,我想你会找到的。其他人则不会 我们发现,今天我们当中没有一个人在过去活得足够长而认识他们。这是我们真诚的愿望 使此记录尽可能准确。要做到这一点,我们必须得到你的帮助。如果你发现一个错误,请通知我 这位作家将反过来更正他的稿件。

我正在尝试从文本文件中读取。此文本文件没有特定的模式,但它是故事的一段。我试图获取每个单词并跟踪它们出现的次数

例如,这是文本文件中的一个练习,用于了解格式

在提交以下记录时,我们意识到我们有错误。其中一些已经被发现并被销毁 即使在模板已经出来之后,也要用钢笔更正。其他的,我想你会找到的。其他人则不会 我们发现,今天我们当中没有一个人在过去活得足够长而认识他们。这是我们真诚的愿望 使此记录尽可能准确。要做到这一点,我们必须得到你的帮助。如果你发现一个错误,请通知我 这位作家将反过来更正他的稿件。我们的目的是重写这个故事,使之更具可读性 包括可用的个人兴趣故事;通过纠正你所犯的错误来提高准确性 可能会发现。前三页是直接从表兄写的家庭记录中取得的,没有任何变化 埃塞尔·玛兹·卡尔·马什。我们非常感谢这里提供的这一信息。如果没有她的帮助,事情会变得更糟 除了但以理和大卫的父母,不可能回到过去。如历史所述,四个马什兄弟 在1761年以前的某个时间来到殖民地。离这个日期还有多少年,我们不知道。塞缪尔·马什, 西比迪亚·马什的儿子,生于1761年。我们可以很好地想象,那是他出生前的几年。我们有 研究了他们那个时代英国的记录。那是危险的岁月。许多人来到美国是为了逃避愤怒 一个暴君沼泽国王,其他人逃脱清教徒克伦威尔的审判

我知道如何读取具有特定格式的文件,但我不确定如何读取该文件以查找没有任何标点符号的每个单词


我猜我将使用带有正则表达式的fscanf来实现这一点,但我不能100%确定如何实现这一点。

我说你应该使用
fgets
strtok
。你在评论中说

如果我在设置中使用fgets,会不会超过缓冲区限制?我会不会就这样半途而废呢

如果你使用的是POSIX系统,你可以使用这个函数 将读取一行并正确分配容纳整行的空间。如果你 如果未使用POSIX系统,且
getline
不可用,则可以编写 这样做的
fgets
的包装器

我曾经写过这样的包装,并在过去使用过:

char *fgets_long(FILE *fp)
{
    size_t size = 0, currlen = 0;
    char line[1024];
    char *ret = NULL, *tmp;

    while(fgets(line, sizeof line, fp))
    {
        int wholeline = 0;
        size_t len = strlen(line);

        if(line[len - 1] == '\n')
        {
            line[len-- - 1] = 0;
            wholeline = 1;
        }

        if(currlen + len >= size)
        {
            // we need more space in the buffer
            size += (sizeof line) - (size ? 1 : 0);
            tmp = realloc(ret, size);
            if(tmp == NULL)
                break; // return all we've got so far
            ret = tmp;
        }

        memcpy(ret + currlen, line, len + 1);
        currlen += len;

        if(wholeline)
            break;
    }

    if(ret)
    {
        tmp = realloc(ret, currlen + 1);
        if(tmp)
            ret = tmp;
    }

    return ret;
}
此函数还将给出整行,并为每个行分配内存 它

因此,
geline
解决方案:

char *line = NULL;
size_t len = 0;

// commong word delimiters
const char *delim = " \t.,-!\r\n";

while(getline(&line, &len, fp) > 0)
{
    char *word = strtok(line, delim);

    if(line == NULL)
    {
        fprintf(stderr, "line has delimiters only, ignoring\n");
        continue;
    }

    do {
        do_your_calculations_with(word);
    } while((word = strtok(NULL, delim)));
}

free(line);
或者我的包装纸的解决方案

char *line;
// commong word delimiters
const char *delim = " \t.,-!\r\n";
while((line = fgets_long(fp)))
{
    char *word = strtok(line, delim);

    if(line == NULL)
    {
        fprintf(stderr, "line has delimiters only, ignoring\n");
        continue;
    }

    do {
        do_your_calculations_with(word);
    } while((word = strtok(NULL, delim)));

    free(line);
}

请展示你试过的东西。没有必要发这么长的短信。对不起,你没有表现出任何努力。不,这不是一个正则表达式的例子。我喜欢“如果你犯了一个错误”。“风向标”你无聊吗?你读课文了吗。。。另外,关于正则表达式。它们往往是一个问题,而不是解决方案。当然不适用于您的问题。对不起,我不熟悉POSIX。我如何知道我运行的是哪种系统Linux、BSD、Mac是系统,而Windows不是。对于const char*delim=“\t,-!\r\n”,可以吗;你能给我一个关于什么的概述吗?,-\r\n检查是否存在?
strtok
在遇到
delim
中的一个字符时拆分字符串。在普通文本中,单词由空转义符、制表符、命令、冒号、感叹号、换行符等分隔。我试着在其中放入所有常用的单词分隔符。我忘了分号,你可以把它添加到列表中。我怎么把括号包括进去?只是\)和\(?