gcc 为什么我的c程序不执行cmd时,while循环包括?标签计数在我的程序是不正确的,(Ques更新请参阅)

dkqlctbz  于 2023-03-23  发布在  其他
关注(0)|答案(2)|浏览(105)

所以我的代码是一个程序,它读取html文件中的标记,并显示它们沿着它们出现的次数。对于这个问题,标记被认为是紧接在'〈'之后的字母数字名称,并以'〉'或空格结束的标记。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_TAG_LEN 10
#define MAX_TAGS 100

void htagsA3()
{
    char c;
    int within_tag = 0;
    char tagName[MAX_TAG_LEN];
    int tagNameLen = 0;

    char tags[MAX_TAGS][MAX_TAG_LEN];    //stores tag names
    int tagCounts[MAX_TAGS];              //stores count of each tag
    int numOfTags = 0;
    
    while((c = getchar()) != EOF)
    {
        if(c == '<')
        {
            within_tag = 1;
            tagNameLen = 0;
        }
        else if(c == '>' || c == ' ')
        {
            within_tag = 0;
            tagName[tagNameLen] = '\0';
    
            int i;
            for(i=0; i<numOfTags; i++)
            {
                if(strcmp(tags[i], tagName) == 0)
                {
                    tagCounts[i]++;
                    break;
                }
            }
    
            if(i == numOfTags)
            {
                strncpy(tags[numOfTags], tagName, MAX_TAG_LEN);
                tagCounts[numOfTags] = 1;
                numOfTags++;
            }
        }
        else if(within_tag)
        {
            while(c != ' ')
            {
                if(isalnum(c) && tagNameLen < MAX_TAG_LEN)
                {   
                    tagName[tagNameLen] = c;
                    tagNameLen++;
                }
            }
        }
    }
    
    printf("HTML Tags Found:\n");
    int i;
    for(i=0; i<numOfTags; i++)
    {
        printf("%s: %d\n", tags[i], tagCounts[i]);
    }
}

int main()
{
    htagsA3();
}

我希望能够添加标记名称,直到看到一个空格,所以我使用了while(c!= ' ')。当我编译并运行这个时,cmd卡在一个空行上。如果没有while循环,该程序工作正常,但显示正确的标签名称,但计数是错误的,因为标签计数器是递增的,甚至在空格,我只想计数多少次一个特定的标签已经出现。我在运行时使用输入重定向向程序输入html文件。请帮助我查找错误。
下面是一个示例输出:

HTML Tags Found: 
body: 4
div: 2
p: 6
b: 4
span: 16

正确的计数实际上应该是:

body 1 div 1 p 2 b 2 span 2

下面是输入的示例html文件的内容:

<body lang=EN-CA link=blue vlink="#954F72">
<div class=WordSection1>
<p class=MsoNormal><b><span lang=EN-US style='font-size:14.0pt;font-family: "Times New Roman",serif'>CS 2263</span></b></p>
<p class=MsoNormal><b><span lang=EN-US style='font-size:14.0pt;font-family: "Times New Roman",serif'>Assignment 1</span></b></p>
mutmk8jj

mutmk8jj1#

根据您的描述和代码,问题似乎与else if(within_tag)块中的内部while循环有关。循环永远不会终止,因为循环中c的值不会更新。要解决此问题,您可以使用另一个getchar()调用来更新c的值,并修改循环以检查其他终止条件。以下是代码的更正版本:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_TAG_LEN 10
#define MAX_TAGS 100

void htagsA3()
{
    char c;
    int within_tag = 0;
    char tagName[MAX_TAG_LEN];
    int tagNameLen = 0;

    char tags[MAX_TAGS][MAX_TAG_LEN];    //stores tag names
    int tagCounts[MAX_TAGS];             //stores count of each tag
    int numOfTags = 0;

    while ((c = getchar()) != EOF)
    {
        if (c == '<')
        {
            within_tag = 1;
            tagNameLen = 0;
        }
        else if (c == '>' || c == ' ')
        {
            within_tag = 0;
            tagName[tagNameLen] = '\0';

            int i;
            for (i = 0; i < numOfTags; i++)
            {
                if (strcmp(tags[i], tagName) == 0)
                {
                    tagCounts[i]++;
                    break;
                }
            }

            if (i == numOfTags)
            {
                strncpy(tags[numOfTags], tagName, MAX_TAG_LEN);
                tagCounts[numOfTags] = 1;
                numOfTags++;
            }
        }
        else if (within_tag)
        {
            while (c != ' ' && c != '>' && c != EOF) // Add '>' and EOF as additional termination conditions
            {
                if (isalnum(c) && tagNameLen < MAX_TAG_LEN)
                {
                    tagName[tagNameLen] = c;
                    tagNameLen++;
                }
                c = getchar(); // Update the value of c
            }
        }
    }

    printf("HTML Tags Found:\n");
    int i;
    for (i = 0; i < numOfTags; i++)
    {
        printf("%s: %d\n", tags[i], tagCounts[i]);
    }
}

int main()
{
    htagsA3();
}

这个版本的代码更新了while (c != ' ' && c != '>' && c != EOF)循环中c的值,并增加了两个终止条件,检查c是否等于>EOF。这应该可以防止程序卡在空行上,并允许它按预期处理标记。

6tqwzwtp

6tqwzwtp2#

您发布的程序有几个问题:

  1. char不能保证能够表示值EOF。因此,while((c = getchar()) != EOF)行不能保证工作。您应该将c的数据类型从char更改为int。有关详细信息,请参阅此问题:Why must the variable used to hold getchar's return value be declared as int?
    1.行while(c != ' ')将有效地创建一个无限循环,因为c的值在该循环中不会改变。
    1.您正在多次计数标记。除了'>'字符外,您还对标记中遇到的每个' '字符计数标记。当您在debugger中逐行运行程序并监视所有变量的值时,这一点非常明显。
    问题#1可以通过改变行来解决
char c;

致:

int c;

问题#2可以通过删除while(c != ' ')行来解决,因为该循环的内容应该只执行一次(即循环内容不应该在循环内)。
问题#3可以通过只在c == '>'时计数标签而不是在c == ' '时计数标签来解决。
下面是你的固定代码:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_TAG_LEN 10
#define MAX_TAGS 100

void htagsA3()
{
    int c;
    int within_tag = 0;
    char tagName[MAX_TAG_LEN];
    int tagNameLen = 0;

    char tags[MAX_TAGS][MAX_TAG_LEN];    //stores tag names
    int tagCounts[MAX_TAGS];              //stores count of each tag
    int numOfTags = 0;
    
    while((c = getchar()) != EOF)
    {
        if(c == '<')
        {
            within_tag = 1;
            tagNameLen = 0;
        }
        else if (c == '>' || c == ' ')
        {
            within_tag = 0;
            tagName[tagNameLen] = '\0';

            if ( c == '>' )
            {
                int i;
                for(i=0; i<numOfTags; i++)
                {
                    if(strcmp(tags[i], tagName) == 0)
                    {
                        tagCounts[i]++;
                        break;
                    }
                }
    
                if(i == numOfTags)
                {
                    strncpy(tags[numOfTags], tagName, MAX_TAG_LEN);
                    tagCounts[numOfTags] = 1;
                    numOfTags++;
                }
            }
        }
        else if(within_tag)
        {
            if(isalnum(c) && tagNameLen < MAX_TAG_LEN)
            {   
                tagName[tagNameLen] = c;
                tagNameLen++;
            }
        }
    }
    
    printf("HTML Tags Found:\n");
    int i;
    for(i=0; i<numOfTags; i++)
    {
        printf("%s: %d\n", tags[i], tagCounts[i]);
    }
}

int main()
{
    htagsA3();
}

然而,在修复这些问题后,程序仍然没有给予所需的输出。它输出如下:

HTML Tags Found:
body: 1
div: 1
p: 4
b: 4
span: 4

出现这种情况的原因是,您的程序将开始标记和结束标记视为同一标记的重复项。这是因为您正在通过函数isalnum过滤标记名称,因此结束标记名称中的/被删除,使结束标记的名称与开始标记的名称相同。如果您删除此过滤器,请通过更改行

if(isalnum(c) && tagNameLen < MAX_TAG_LEN)

if(tagNameLen < MAX_TAG_LEN)

然后你的程序有如下输出:

HTML Tags Found:
body: 1
div: 1
p: 2
b: 2
span: 2
/span: 2
/b: 2
/p: 2

正如您所看到的,结束标记现在是单独计数的。

相关问题