You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含while循环的C语言HTML标签统计程序CMD运行异常及计数错误

HTML标签统计程序错误排查与修复

我编写了一段C语言程序,用于读取HTML文件中的标签并统计各标签的出现次数。本次问题中,标签定义为紧跟<的字母数字名称,以>或空格结束。为读取完整标签名,我添加了while(c != ' ')循环,但编译运行后CMD陷入停滞;移除该循环后程序可运行,但标签计数错误(空格也会触发计数)。我通过输入重定向传入HTML文件,示例输入对应的正确计数应为body 1、div 1、p 2、b 2、span 2,当前输出计数远大于正确值,请求排查程序错误。

原代码

#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();
}

示例输入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>

当前错误输出

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

期望正确输出

body: 1
div: 1
p: 2
b: 2
span: 2

错误分析

  1. 死循环问题:原代码中else if(within_tag)分支里的while(c != ' ')循环没有读取新的字符,一旦进入该循环,c的值永远不会改变,导致程序陷入死循环,CMD停滞。
  2. 重复计数问题:原逻辑中,遇到>或空格就触发计数,但标签属性中的空格(比如<body lang=EN-CA>里的空格)会多次触发统计,导致同一个标签被重复计数。
  3. 标签名收集逻辑漏洞:没有处理无空格的标签(比如<b>),且没有判断标签名是否为空,空字符串也会被统计,同时strncpy没有确保字符串终止,存在内存越界风险。

修正后的代码

#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];    // 存储标签名
    int tagCounts[MAX_TAGS];              // 存储标签计数
    int numOfTags = 0;
    
    while((c = getchar()) != EOF)
    {
        if(c == '<')
        {
            // 进入标签区域,重置标签名长度
            within_tag = 1;
            tagNameLen = 0;
        }
        else if(within_tag)
        {
            // 遇到标签结束符,处理当前标签
            if(c == '>' || c == ' ')
            {
                within_tag = 0;
                // 仅当标签名有效(长度>0)时才统计
                if(tagNameLen > 0)
                {
                    tagName[tagNameLen] = '\0';
                    int i;
                    for(i=0; i<numOfTags; i++)
                    {
                        if(strcmp(tags[i], tagName) == 0)
                        {
                            tagCounts[i]++;
                            break;
                        }
                    }
                    if(i == numOfTags && numOfTags < MAX_TAGS)
                    {
                        // 确保字符串终止,避免内存越界
                        strncpy(tags[numOfTags], tagName, MAX_TAG_LEN - 1);
                        tags[numOfTags][MAX_TAG_LEN - 1] = '\0';
                        tagCounts[numOfTags] = 1;
                        numOfTags++;
                    }
                }
            }
            // 收集标签名的有效字符(字母数字)
            else if(isalnum(c) && tagNameLen < MAX_TAG_LEN - 1)
            {
                tagName[tagNameLen] = c;
                tagNameLen++;
            }
            // 遇到非有效字符,退出标签状态,不统计
            else
            {
                within_tag = 0;
            }
        }
        // 非标签区域的字符直接忽略
    }
    
    printf("HTML Tags Found:\n");
    for(int i=0; i<numOfTags; i++)
    {
        printf("%s: %d\n", tags[i], tagCounts[i]);
    }
}

int main()
{
    htagsA3();
}

内容的提问来源于stack exchange,提问作者goldengomi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:33:13