含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
错误分析
- 死循环问题:原代码中
else if(within_tag)分支里的while(c != ' ')循环没有读取新的字符,一旦进入该循环,c的值永远不会改变,导致程序陷入死循环,CMD停滞。 - 重复计数问题:原逻辑中,遇到
>或空格就触发计数,但标签属性中的空格(比如<body lang=EN-CA>里的空格)会多次触发统计,导致同一个标签被重复计数。 - 标签名收集逻辑漏洞:没有处理无空格的标签(比如
<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
相关产品推荐
相关产品推荐

