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

相关文章

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex