在我的课上,我必须阅读福尔摩斯的所有文本,并找到所有的对话.对话应该在两个引号内进行.

我试过的一切,我都不能始终如一地得到对话.在查看作业(job)中使用的文本和URL时,偶尔会缺少引号.这显然是由于语法,如果一个字符的讲话时间超过一个段落,那么每个新段落都会出现左引号,但右引号"标记只会出现在最后一段讲话的结尾.

由于这种情况的随机性,我发现这是不可能的,但我找到了一个可能的解决方案:如果我的引号状态变量等于1,并且出现第二个引号,我必须判断并查看是否有两个换行符,如果为真,则引号不计算并继续到结尾.

我一直在try 使用多个文件流指针来查找当前字符、前一个字符和前一个减go 一个字符,但我找不到这样做的方法.似乎不可能让多个指针指向同一个文件,但我不能100%确定.这真的是不可能的吗?

摘要:我遇到了一个运行时错误,我似乎永远找不到一致的对话.根据允许随机不放置结束引号的语法规则,似乎是不可能的.在我的脑海里,这让我觉得我充其量只能得到对话和叙述的混合.我try 创建多个文件流指针来查找当前、上一个和上一个字符减go 一个字符,但不起作用.

我的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查找前一个和前一个减go 一个字符.它似乎不工作,我的日志(log)判断这些东西是否工作不打印到终端.

推荐答案

"This is apparently due to grammar..."不.这就是连续演讲对书面对话的读者来说是如何signalled.

您提供的代码太长,将tweak混淆为可用的形式(对不起).
三(!)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."

代码是有效的,但正如你所看到的,短语已经被打破,混淆了对谁说了什么的理解.解决这个问题超出了操作员的问题范围.可以编写post processing个过滤器,以剔除作者在原文中拆分的空白行和connect-up个短语.


EDIT:
代码沼泽的many个问题之一是它隐藏小但后果错误的能力……

    char charIterator;

    /* ... */

    while( (charIterator = fgetc(newlyWrittenFile)) != EOF )

重复了这么多次,在这里,"EOF is NOT a single byte char"

C++相关问答推荐

Pure Win32 C(++)-除了替换控件的窗口程序之外,还有其他方法可以在输入时禁用按钮吗?

在函数中使用复合文字来初始化C语言中的变量

ATmega328P EEPROM未写入

如何在C语言中正确打印图形

对重叠字符串使用MemMove

为什么函数是按照定义的顺序执行的,而不是按照从avr-c中的int main()调用的顺序执行的?

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

如何使用libgpio(d)为Raspberry Pi编译C程序?

Caesar密码调试:输出文本末尾的问号和随机字符

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

仅从限制指针参数声明推断非混叠

错误:字符串在C中获得意外输出

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

C++中PUTS函数的返回值

某些EAX值的不同调用方的CPUID结果不一致

即使客户端不发送数据,也会发生UNIX套接字读取

Ubuntu编译:C中的文件格式无法识别错误

中位数和众数不正确

C11 嵌套泛型

strlen 可以是[[未排序]]吗?