C //练习 6-1 上述getword函数不能正确处理下划线、字符串常量、注释及预处理控制指令。请编写一个更完善的getword函数。

本文主要是介绍C //练习 6-1 上述getword函数不能正确处理下划线、字符串常量、注释及预处理控制指令。请编写一个更完善的getword函数。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C程序设计语言 (第二版) 练习 6-1

练习 6-1 上述getword函数不能正确处理下划线、字符串常量、注释及预处理控制指令。请编写一个更完善的getword函数。

注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010

 

代码块:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>#define MAXWORD 100
#define NKEYS (sizeof keytab / sizeof(keytab[0]))
#define MAXOP 100
#define NUMBER '0'
#define MAXVAL 100
#define BUFSIZE 100
#define VAR '1'char buf[BUFSIZE];
int bufp = 0;struct key{char *word;int count;
};int getch(void){return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c){if(bufp >= BUFSIZE){printf("Ungetch! Too many characters!\n");}else{buf[bufp++] = c;}
}int getword(char *word, int lim) {int c;char *w = word;static int line_beg = 1; /* 1 at beginning of a new line */static int after_slash = 0; /* 1 after '\' */int after_star = 0; /* 1 after '*' */if(isspace(c = getch()))after_slash = 0;while(isspace(c)) {if(c == '\n')line_beg = 1;c = getch();}if(c != EOF)*w++ = c;if(c == '#' && line_beg == 1) { /* Preprocessor directive */while((c = getch()) != '\n' && c != EOF) /* Go to end of line */;return getword(word, lim); /* Start over */}line_beg = 0;if(c == '\\') /* Set after_slash flag */after_slash = after_slash ? 0 : 1; /* Ignore '\\' comment */else if(c == '/' ) {if((c = getch()) == '*' && !after_slash) { /* Begin comment */while((c = getch()) != EOF) {if(c == '/') {if(after_star) /* End comment */return getword(word, lim); /* Start over */}else if(c == '*' && !after_slash)after_star = 1;else if(c == '\\')after_slash = after_slash ? 0 : 1; /* Ignore '\\' comments */else {after_star = 0;after_slash = 0;}}} /* End comment */after_slash = 0; /* Not after slash anymore */if(c != EOF)ungetch(c);}else if(c == '\"') {if(!after_slash) { /* String literal */--w; /* Reset w */while((c = getch()) != EOF) {if(c == '\"' && !after_slash)break;else if(c == '\\')after_slash = after_slash ? 0 : 1; /* Ignore '\\' comments */elseafter_slash = 0;*w++ = c;}*w = '\0';if(c == EOF)return EOF;elsereturn getword(word, lim); /* Start over. */}after_slash = 0; /* Not after a slash anymore. */}if(!isalpha(c) && c != '_') { /* It's a symbol. */*w = '\0';if(c != '\\')after_slash = 0;return c;}/* Reset this flag since a slash would have just returned. */after_slash = 0;for( ; --lim > 0; ++w) /* It's a word or letter. */if(!isalnum(*w = getch()) && *w != '_') {ungetch(*w);break;}*w = '\0';return word[0];}int binsearch(char *word, struct key tab[], int n){int cond;int low, high, mid;low = 0;high = n - 1;while(low <= high){mid = (low + high) / 2;if((cond = strcmp(word, tab[mid].word)) < 0){high = mid - 1;}else if(cond > 0){low = mid + 1;}else{return  mid;}}return -1;
}int main(){struct key keytab[] = {{"auto", 0}, {"break", 0}, {"case", 0}, {"char", 0}, {"const", 0}, {"continue", 0}, {"default", 0},{"do", 0}, {"double", 0}, {"else", 0}, {"enum", 0}, {"extern", 0}, {"float", 0}, {"for", 0}, {"goto", 0}, {"if", 0}, {"int", 0},{"long", 0}, {"register", 0}, {"return", 0}, {"short", 0}, {"signed", 0}, {"sizeof", 0}, {"static", 0}, {"struct", 0}, {"switch", 0},{"typedef", 0}, {"unsigned", 0}, {"union", 0}, {"void", 0}, {"volatile", 0}, {"while", 0}};int n;char word[MAXWORD];while(getword(word, MAXWORD) != EOF){if(isalpha(word[0])){if((n = binsearch(word, keytab, NKEYS)) >= 0){keytab[n].count++;}}}for(n = 0; n < NKEYS; n++){if(keytab[n].count > 0){printf("%4d %s\n", keytab[n].count, keytab[n].word);}}system("pause");return 0;
}

这篇关于C //练习 6-1 上述getword函数不能正确处理下划线、字符串常量、注释及预处理控制指令。请编写一个更完善的getword函数。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/619100

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字