C 这个扫描文件并返回行数/段落数/字数的程序有什么问题?

C 这个扫描文件并返回行数/段落数/字数的程序有什么问题?,c,loops,infinite,C,Loops,Infinite,我编写这个程序是为了接受一个文件并扫描文件中的行数、段落数和单词数 问题是,它永远不会停止扫描。它永远不会出现在while(nextChar!='\n')循环中。因此processBlank和copyText函数从未停止运行。它永远不会击中EOF 我不知道如何进行。我无法找到解决方案,因此非常感谢您的帮助:) #包括 #包括 无效初始化(int*p1、int*p2、int*p3、int*p4) { *p1=0; *p2=0; *p3=0; *p4=0; } void processBlank(c

我编写这个程序是为了接受一个文件并扫描文件中的行数、段落数和单词数

问题是,它永远不会停止扫描。它永远不会出现在while(nextChar!='\n')循环中。因此processBlank和copyText函数从未停止运行。它永远不会击中EOF

我不知道如何进行。我无法找到解决方案,因此非常感谢您的帮助:)

#包括
#包括
无效初始化(int*p1、int*p2、int*p3、int*p4)
{
*p1=0;
*p2=0;
*p3=0;
*p4=0;
}
void processBlank(char*nextChar,int*wordsinLine,FILE*ctPtr)
{
而(*nextChar=='')
{
printf(“%c”,*nextChar);
*nextChar=fgetc(ctPtr);
}
*wordsinLine+=1;
}
无效copyText(char*nextChar,FILE*ctPtr)
{
而(*nextChar!='')
{
printf(“%c”,*nextChar);
*nextChar=fgetc(ctPtr);
}
}
void updateCount(int*numWords,int*wordsinLine,int*numParagraphs,int*numLines)
{
*numWords+=*字行;
如果(*wordsinLine==0)
*numParagraphs+=1;
*wordsinLine=0;
*numLines+=1;
}
void printTotal(int numWords、int numLines、int numParagraphs)
{
printf(“\n\n\n\n总字数为:%d\n\n”,numWords);
printf(“总行数为:%d\n\n”,numLines);
printf(“段落总数为:%d\n\n\n\n”,numParagraphs);
}
void main()
{
int numWords、numLines、numParagraphs、wordsinLine;
初始化(&numWords,&numLines,&numParagraphs,&wordsinLine);
文件*ctPtr;
char nextChar;
if((ctPtr=fopen(“Q2read.txt”,“r”))==NULL)
printf(“无法打开文件\n”);
其他的
{
nextChar=fgetc(ctPtr);
while(nextChar!=feof(ctPtr))
{
而(nextChar!='\n')
{
processBlank(&nextChar,&wordsinLine,ctPtr);
copyText(&nextChar,ctPtr);
}
更新帐户(&numWords,&wordsinLine,&numParagraphs,&numLines);
}
printTotal(numWords、numLines、numParagraphs);
fclose(ctPtr);
}
}
fgetc()
返回一个int,而
EOF
通常为-1。将nextChar声明为int并根据
EOF
检查它(不是
feof()
feof()
是一个测试流的EOF的函数)


您可以改为选中
feof(stream)!=0
(比如使用
if(feof(stream))
)查看您是否处于EOF,但我认为只检查
fgets()
的返回值更好。

与其逐字节读取文件,(速度非常慢),不如查看
fgets()
函数。这将为您获得一整行文本,然后您可以从那里处理它。它确实需要一个最大字符串长度,因此如果您使用合理的值,例如1024,请始终确保检查字符串中是否有换行符,如果它不在字符串中,则需要再次读取并追加,但在执行之前,请检查您是否真的处于EOF,因为许多文件可能没有最后的
\n
,或
\r\n
,或者
\r
,或者您正在使用的操作系统使用的任何疯狂

  • 专业:改变
    nextChar=feof(ctPtr)
    nextChar!=EOF

    feof()
    设置“
    EOF
    是一个负数。
    两种不同的东西-不具有很好的可比性

  • 次要:将
    void main()
    更改为
    int main(void)

  • char-nextChar
    更改为
    int-nextChar
    (以及相关函数调用)

  • 主要:
    copyText()
    :在(*nextChar!=''&&*nextChar!=EOF){

  • main()


  • 感谢您的及时回复!我尝试了您的建议,代码的运行方式与我发布的完全相同。我假设它将看到文件的结尾,只要它能够脱离嵌套的while循环。nextChar!='\n'似乎从来都不是错误的。我还尝试添加while(nextChar!=10)(新行的ascii代码)也不退出循环不同意“check feof(stream)>0”。
    feof
    函数在文件末尾返回非零,不一定是正数。建议改为
    if(feof(stream))
    @chux我同意并将更新我的答案。我试图避免匹配-1,(我的feof手册页似乎认为这可能表明存在错误),但忽略错误并继续下去并没有多大意义,因为关于
    fgets()
    fgetc()
    的性能差异,任何支持“难以置信的慢”的基准测试?我手头没有任何基准测试,但想象一下。假设您正在读取一个非常大的文件,1兆字节,平均行长为1024个字符。这意味着您将对文件中的每行调用该函数1024次(平均),这本身似乎没什么大不了的,因为大部分文件可能都会加载到文件缓存中。但是,在C中调用函数需要时间。必须将内容推送到堆栈中,弹出,然后执行,然后返回。fgets()这是一次函数调用完成的。看到区别了吗?@chux给函数调用增加了10纳秒的开销(这是很合理的),一个字节一个字节地读取一个千兆字节会增加10秒的开销。这不是一个大问题,但不值得养成这样的习惯。还有一个更好的函数可以使用:
    getline()
    。作为POSIX-2008标准的一部分,它真的得到了整条线,在整个过程中为它分配了足够的空间。这避免了缓冲区限制带来的许多麻烦。@chux好吧,如果
    fgets()
    是使用
    fgetc()
    实现的,那么该实现要么依赖于编译器内联,要么是一个普通的实现
    #include <stdio.h>
    #include <stdlib.h>
    
    void initialize(int *p1,int *p2,int *p3,int *p4)
    {
        *p1=0;
        *p2=0;
        *p3=0;
        *p4=0;
    }
    
    void processBlank(char *nextChar,int *wordsinLine,FILE *ctPtr)
    {
        while (*nextChar==' ')
        {
            printf("%c",*nextChar);
            *nextChar=fgetc(ctPtr);
        }
        *wordsinLine+=1;
    }
    
    void copyText(char *nextChar,FILE *ctPtr)
    {
        while (*nextChar!=' ')
        {
            printf("%c",*nextChar);
            *nextChar=fgetc(ctPtr);
        }
    }
    
    void updateCount(int *numWords,int *wordsinLine,int *numParagraphs,int *numLines)
    {
        *numWords+=*wordsinLine;
        if (*wordsinLine==0)
            *numParagraphs+=1;
        *wordsinLine=0;
        *numLines+=1;
    }
    
    void printTotal(int numWords,int numLines,int numParagraphs)
    {
        printf("\n\n\n\nTotal number of words is: %d\n\n",numWords);
        printf("Total number of lines is: %d\n\n",numLines);
        printf("Total number of paragraphs is: %d\n\n\n\n",numParagraphs);
    }
    
    void main()
    {
        int numWords,numLines,numParagraphs,wordsinLine;
        initialize(&numWords,&numLines,&numParagraphs,&wordsinLine);
        FILE *ctPtr;
        char nextChar;
        if ((ctPtr=fopen("Q2read.txt", "r"))==NULL)
            printf("File could not be opened\n");
        else
        {
            nextChar=fgetc(ctPtr);
            while (nextChar!=feof(ctPtr))
            {
    
                while (nextChar!='\n')
                {
                    processBlank(&nextChar,&wordsinLine,ctPtr);
                    copyText(&nextChar,ctPtr);
                }
                updateCount(&numWords,&wordsinLine,&numParagraphs,&numLines);
            }
            printTotal(numWords,numLines,numParagraphs);
            fclose(ctPtr);
        }
    }