C //练习 5-18 修改dcl程序,使它能够处理输入中的错误。

这篇具有很好参考价值的文章主要介绍了C //练习 5-18 修改dcl程序,使它能够处理输入中的错误。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C程序设计语言 (第二版) 练习 5-18

练习 5-18 修改dcl程序,使它能够处理输入中的错误。

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

 文章来源地址https://www.toymoban.com/news/detail-788515.html

代码块:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXTOKEN 100

enum { NAME, PARENS, BRACKETS };
enum { ERR_YES, ERR_NO };

void dcl(void);
void dirdcl(void);

int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN]; 
char datatype[MAXTOKEN]; 
char out[1000]; 
int errtoken = ERR_NO;

int main() {
    while (gettoken() != EOF) {
        strcpy(datatype, token); 
        out[0] = '\0';
        dcl();
        if (tokentype != '\n')
            printf("syntax error\n");
        printf("%s: %s %s\n", name, out, datatype);
    }
    return 0;
}

/* dcl: parse a declarator */
void dcl(void) {
    int ns;

    for (ns = 0; gettoken() == '*'; ) 
        ns++;
    dirdcl();
    while (ns-- > 0)
        strcat(out, " pointer to");
}

void paramdcl(void);

void dirdcl(void) {
    int type;

    if (tokentype == '(') { 
        dcl();
        if (tokentype != ')') {
            printf("missing )\n");
            errtoken = ERR_YES;
        }
    } else if (tokentype == NAME) 
        strcpy(name, token);
    else {
        printf("error: expected name or (dcl)\n");
        errtoken = ERR_YES;
    }

    while ((type=gettoken()) == PARENS || type == BRACKETS || type == '(')
        if (type == PARENS)
            strcat(out, " function returning");
        else if (type == '(') {
            strcat(out, " function expecting");
            paramdcl();
            strcat(out, " and returning");
        } else {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");
        }
}

void dclspec(void);

void paramdcl(void) {
    do {
        dclspec();
    } while (tokentype == ',');

    if (tokentype != ')')
        printf("error: missing ) in parameter declaration");
}

int typespecifier(void);
int typequalifier(void);

void dclspec(void) {
    char temp[MAXTOKEN];
    temp[0] = '\0';
    gettoken();

    do {
        if (tokentype != NAME) {
            errtoken = ERR_YES;
            dcl();
        } else if (typespecifier() || typequalifier()) {
            strcat(temp, " ");
            strcat(temp, token);
            gettoken();
        } else {
            printf("error: unknown type in param list\n");
            errtoken = ERR_YES;
        }
    } while (tokentype != ',' && tokentype != ')');

    strcat(out, temp);
    if (tokentype == ',')
        strcat(out, ",");
}

int compare(const void *s, const void *t);

int typespecifier(void) {
    static char *type[] = { "char", "int", "void" };
    char *pt = token;

    if (bsearch(&pt, type, sizeof(type)/sizeof(char *), sizeof(char *), compare) == NULL)
        return 0;
    return 1;
}

int typequalifier(void) {
    static char *type[] = { "const", "volatile" };
    char *pt = token;

    if (bsearch(&pt, type, sizeof(type)/sizeof(char *), sizeof(char *), compare) == NULL)
        return 0;
    return 1;
}

int compare(const void *s, const void *t) {
    char **chs;
    char **cht;
    chs = (char **) s;
    cht = (char **) t;
    return strcmp(*chs, *cht);
}

int getch(void);
void ungetch(int);

int gettoken(void) {
    int c;
    char *p = token;

    if (errtoken == ERR_YES) {
        errtoken = ERR_NO;
        return tokentype;
    }

    while ((c = getch()) == ' ' || c == '\t')
        ;

    if (c == '(') {
        if ((c = getch()) == ')') {
            strcpy(token, "()");
            return tokentype = PARENS;
        } else {
            ungetch(c);
            return tokentype = '(';
        }
    } else if (c == '[') {
        for (*p++ = c; (*p++ = getch()) != ']'; )
            ;
        *p = '\0';
        return tokentype = BRACKETS;
    } else if (isalpha(c)) {
        for (*p++ = c; isalnum(c = getch()); )
            *p++ = c;
        *p = '\0';
        ungetch(c);
        return tokentype = NAME;
    }

    return tokentype = c;
}

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0; 

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;
}

到了这里,关于C //练习 5-18 修改dcl程序,使它能够处理输入中的错误。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序 - 修改多行文本输入框 placeholder 属性换行显示文字样式的详细教程

    多行文本输入框是微信小程序中常用的组件之一,而placeholder属性则用于在输入框中显示提示文本。然而,默认情况下,placeholder属性中的文字无法实现换行显示,这可能会导致在一些情况下显示不完整或不够明确。在本篇教程中,我将详细介绍如何修改多行文本输入框的pl

    2024年02月03日
    浏览(51)
  • ChatGPT能够处理长篇对话吗?

    是的,ChatGPT可以处理长篇对话。虽然GPT模型是为生成连续文本而设计的,但它也可以应对长篇对话的挑战。下面是对ChatGPT处理长篇对话的详细分析。 1. 上下文理解和延续性:ChatGPT能够记住之前的对话历史,并将其作为上下文来理解后续的对话内容。它可以根据先前的对话语

    2024年02月08日
    浏览(63)
  • 事件驱动编程:如何在应用程序中处理用户输入和交互

    [toc] 引言 1.1. 背景介绍 随着互联网技术的快速发展,应用程序被广泛应用于人们的生活和工作中。在这些应用程序中,用户输入和交互是必不可少的组成部分。如何优雅地处理用户输入和交互,让应用程序更加符合用户的使用习惯,是摆在每个程序员面前的一个重要问题。

    2024年02月07日
    浏览(60)
  • 微信小程序中键盘弹起输入框自动跳到键盘上方处理

    键盘未弹起时 键盘弹起后: 话就不多说了 我直接贴代码了 原理就是用你点击的输入框的底部 距离顶部的位置 减去屏幕高度除以2,然后设成负值,再将这个值给到最外层相对定位的盒子的top属性,这样就不会出现顶部导航上移的问题了具体实现如下: 首先封装一个js工具包

    2024年02月13日
    浏览(109)
  • ChatGPT是否能够处理多模态数据和多模态对话?

    ChatGPT有潜力处理多模态数据和多模态对话,这将进一步扩展其在各种应用领域中的实用性。多模态数据是指包含多种不同类型的信息,例如文本、图像、音频和视频等。多模态对话是指涉及多种媒体形式的对话交流,例如同时包含文本和图像的对话。 **1. 多模态数据处理:

    2024年02月14日
    浏览(52)
  • 网站是如何进行访问的?在浏览器地址栏输入网址并回车的一瞬间到页面能够展示回来,经历了什么?

    这个问题是检验web和计网学习程度的经典问题。 网站访问流程: 1) 在输入完一个域名之后,首先是检查浏览器自身的DNS缓存是否有相应IP地址映射,如果没有对应的解析记录,浏览器会查找本机的hosts配置文件(一般是C:WindowsSystem32driversetchosts,这个文件是用于在操作系统

    2024年02月14日
    浏览(59)
  • 小程序this.setData修改对象、数组中的值

    在微信小程序的前端开发中,使用this.setData方法修改data中的值,其格式为 this.setData({ ‘参数名1’: 值1,‘参数名2’: 值2)} 注意:如果是简单变量,参数名可以不加引号。 下面提供2种方式对data中的对象、数组中的数据进行修改: 假设原数据为: 方式一:使用[‘字符串’]

    2024年04月25日
    浏览(37)
  • 微信小程序 修改三方组件中的自带样式

    众所周知,微信小程序会引用诸如vant,weiui等三方组件,当我们想要对组件自带样式进行修改的时候该怎么做呢? 1.在调试器中找到想要修改样式的组件的class类名,在对应的wxss中添加样式,此时样式未生效; 2.官方文档中提到可以在externalclass中添加一个类名暴露给父组件,

    2024年02月12日
    浏览(54)
  • 微信小程序怎么修改自定义组件中的样式

    在微信小程序中我们经常要用到自定义组件,但是有时我们因为引用的地方不同可能组件的一些样式也要修改,比如颜色,高度,宽度等来适合不同的页面,有没有办法来修改自定义组件中的样式呢,很显然是有的,我们要用到externalClasses方法。 一.自定义子组件: component

    2024年02月12日
    浏览(68)
  • Python二级 每周练习题18

    从键盘输入任意字符串,按照下面要求分离字符串中的字符: 1、分别取出该字符串的第偶数位的元素(提醒注意:是按照从左往右数的方式确定字符串的位置) 2、并依次存储到一个列表中; 3、输出这个列表。 答案: 编写程序帮老师对英语试卷中的英文字母、数字和其他字符(注意

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包