如何使用 fseek 和文件流指针在 C 中查找文件的前一个和前一个减一个元素

问题描述 投票:0回答:1

对于我的课,我必须拿走夏洛克·福尔摩斯的所有文本并找到所有对话。对话应该发生在两个引号内“

我尝试过的一切,都无法始终如一地获得对话。当查看作业中使用的文本及其来源的 URL 时,有时会缺少引号。这显然是由于语法造成的,如果一个角色说话的时间超过一个段落,则每个新段落都会出现开引号,但结束引号“标记仅出现在最后一段语音的末尾。

由于这种情况发生的随机性,我发现这是不可能的,但找到了一个可能的解决方案:如果我的引用状态变量等于 1 并且出现第二个引号,我必须检查并查看是否有 2 个换行符,如果true 那么引号不计算在内并继续直到结束。

我一直在尝试使用多个文件流指针来查找当前字符、前一个字符和前一个减一个字符,但我找不到一种方法来做到这一点。似乎不可能将多个指针指向同一个文件,但我不能 100% 确定。这实际上是不可能的吗?

摘要:我遇到运行时错误,我似乎永远无法一致地找到对话。根据允许随机不放置结束引号的语法规则,这似乎是不可能的。在我看来,这让我认为我最多只能得到对话和叙述的混合。已尝试创建多个文件流指针来查找当前、上一个和上一个减去一个字符,但它不起作用。

我的 C 程序有问题的特定函数:

void findDialogueInFile(char* filename)
{
    FILE *newlyWrittenFile = fopen(filename, "r");

    if (newlyWrittenFile == NULL)
    {
        printf("\nFile could not be opened");
    }
    else
    {
        printf("\nNewlyWrittenFile is readable");
    }

    char charIterator;
    
    int doubleQuoteCounter = 0;

    FILE *quoteCheckerFile = fopen("quoteChecker.txt", "w");

    if (quoteCheckerFile == NULL)
    {
        printf("\nFile could not be opened");
    }
    else
    {
        printf("\nquoteChecker is writeable");
    }

   int singleQuoteCounter = 0;

   FILE *previousElementOfStreamPointer = fopen("quoteChecker.txt", "r");

   FILE *ElementMinus2OfStreamPointer = fopen("quoteChecker.txt", "r");

   char previousCharElement;

   char previousCharElementMinus2;

   int lengthOfStringArrayCounter = 0;

   if (previousElementOfStreamPointer == NULL)
    {
        printf("\nFile could not be opened");
    }
    else
    {
        printf("\nquoteChecker is readable with previousElementOfStreamPointer");
    }

   if (ElementMinus2OfStreamPointer == NULL)
    {
        printf("\nFile could not be opened");
    }
    else
    {
        printf("\nquoteChecker is readable with elementMinus2OfStreamPointer");
    }

    /// vvvvv where the magic happens vvvvv

    while( (charIterator = fgetc(newlyWrittenFile)) != EOF )
    {
        
        fseek(previousElementOfStreamPointer, -1L, SEEK_CUR);

        fseek(ElementMinus2OfStreamPointer, -2L, SEEK_CUR);


        previousCharElement = fgetc(previousElementOfStreamPointer);

        previousCharElementMinus2 = fgetc(ElementMinus2OfStreamPointer);

        if (charIterator == '\"')
        {
            if(previousCharElement == '\n' && previousCharElementMinus2 == '\n')
            {
                printf("\nFOUND DIALOGUE LONGER THAN A PARAGRAPH\n");
                continue;
            }
            fprintf(quoteCheckerFile, "%c", charIterator);
            doubleQuoteCounter++;
        }
        else if (singleQuoteCounter >= 2)
        {
            fprintf(quoteCheckerFile, "\n");
            singleQuoteCounter = 0;
            //doubleQuoteCounter = 0;
            continue;
        }
        else if (doubleQuoteCounter == 1)
        {

            if (charIterator == '\'')
            {
                singleQuoteCounter++;
            }
            
            fprintf(quoteCheckerFile, "%c", charIterator);
        }
        else if (doubleQuoteCounter >= 2)
        {
            fprintf(quoteCheckerFile, "\n\n");
            doubleQuoteCounter = 0;
        }

   }

    fclose(newlyWrittenFile);
    fclose(quoteCheckerFile);

    return ;

}

我期望能够使用多个指针一次找到文件中的不同位置,并使用 fseek 查找前一个和前一个减一个字符。它似乎不起作用,我检查这些东西是否工作的日志没有打印到终端。

c file pointers file-io file-pointer
1个回答
0
投票

这显然是由于语法原因......”不。这就是连续语音向书面对话读者发出信号的方式。

您提供的代码太长,并且混乱地

调整成可用的形式(抱歉)。三个(!)
FILE

指针,计数器和标志......这太多了!

如评论中所述,您的代码只需要跟踪最近看到的几个字符即可确定双引号是否表示一段语音的结束,或一个字符独白的继续。

另一个简化是将程序编写为“

filter”,这样您就不需要为文件名和指针而烦恼。让操作系统和 C 库承担一些负载。

下面是哈珀·李的《杀死一只知更鸟》的一小段摘录,用作示例文本。 (最后一句已被拆分为“独白延续”示例。)

"How old are you," asked Jem, "four-and-a-half?" "Goin' on seven." "Shoot no wonder, then," said Jem, jerking his thumb at me. "Scout yonder's been readin' ever since she was born, and she ain't even started to school yet. "You look right puny for goin' on seven."
这是一些代码:

void excerptDialogue() { int ch, prv[ 2 ] = { 0 }, inQuote = 0; while( ( ch = getchar() ) != EOF ) { if( ch == '\"' ) { if( !inQuote ) inQuote = 1; else { if( prv[1] && ( prv[0] != '\n' || prv[1] != '\n' ) ) { // exiting quote putchar( ch ); putchar( '\n' ); // inject LF for readable output inQuote = 0; } } } if( inQuote ) putchar( ch ); prv[1] = prv[0]; prv[0] = ch; } } int main( void ) { excerptDialogue(); return 0; }
这是结果:

"How old are you," "four-and-a-half?" "Goin' on seven." "Shoot no wonder, then," "Scout yonder's been readin' ever since she was born, and she ain't even started to school yet. "You look right puny for goin' on seven."
代码可以工作,但是,正如您所看到的,短语已被破坏,混淆了谁对谁说了什么的理解。解决这个问题超出了OP问题的范围。

© www.soinside.com 2019 - 2024. All rights reserved.