最近开始自学C语言,在看K&R的《C程序设计语言》。练习2-3要求写一个函数,将输入的十六进制数字字符串转换成与之等价的整数值,配套答案没有扩展程序的通用性,所以我就稍微改造改造。

  配套的答案是这样的(自己添加了注释):

 #define YES    1
#define NO 0 /* htoi:将十六进制数字字符串转换成十进制数
* 如果发现'0x'或'0X'则跳过并设置十六进制数的起点
* 检查后续字符是否是0-9,a-f或是A-F
* 如果是则将其转换为整形
* 如果不是则停止检查,数字结束
* 通过公式计算相应的十进制值并返回
*/
int htoi(char s[])
{
int hexdigit,i,inhex,n; if (s[i] == '') {
++i;
if (s[i] == 'x' || s[i] == 'X'){
++i;
}
}
n = ; /* 初始化返回变量 */
inhex = YES; /* 假设在合法字符中 */
for ( ; inhex == YES; ++i) {
if (s[i] >= '' && s[i] <= '')
hexdigit = s[i] - '';
else if (s[i] >= 'a' && s[i] <= 'f')
hexdigit = s[i] - 'a' + ;
else if (s[i] >= 'A' && s[i] <= 'F')
hexdigit = s[i] - 'A' + ;
else
inhex = NO;
if (inhex == YES)
n = * n + hexdigit;
}
return n;
}

  该函数需要导入一个字符数组,我在 main() 函数中写了获取数组的代码将获取字符数组的代码写成(假设最多获取10个长度的字符数组,因为数组以 '\0' 结尾,因此总共最多获取9个有效字符):

 int c,i;
char input[]; for ( i = ; i < - && ((c = getchar()) != EOF); ++i)
input[i] = c;
input[i] = '\0';

  将得到的字符数组传入 htoi() 函数中即可计算出转换后的值。

  但是这样有个缺陷:字符数组开头必须是 “0x” 或 “0X” 或 数字0-9 或 字母a-f 或 A-F,否则 htoi() 函数只返回 0。这样就降低了程序的通用性,那么如何才能当字符数组前头包含无用字符时,只有检测到 “0x” 或 “0X” 时才继续检测后续字符,并计算返回正确的结果?

  我的做法是在 htoi() 函数中检测是否为 “0x” 或 “0X” 的代码上添加循环:

 int htoi(char s[])
{
int hexdigit,i,inhex,n; i=;
while (s[i] != '\0'){
if (s[i] == '') {
++i;
if (s[i] == 'x' || s[i] == 'X'){
++i;
break; /* 如果是“0x”或“0X”就停止循环 */
}
}
else
++i; /* 如果不符合则循环到底,最后s[i]='\0' */
}
n = ;
inhex = YES;
for ( ; inhex == YES; ++i) {
... ...

  运行结果如下:

  下面把完整代码贴出来,若有幸让高手看见还请指点指点:

 #include <stdio.h>

 #define YES    1
#define NO 0 int htoi(char s[]); int main(void)
{
int c,i;
char input[]; for ( i = ; i < - && ((c = getchar()) != EOF); ++i)
input[i] = c;
input[i] = '\0';
printf("输入的16进制数转换十进制数:%d\n",htoi(input));
return ;
} int htoi(char s[])
{
int hexdigit,i,inhex,n; i=;
while (s[i] != '\0'){
if (s[i] == '') {
++i;
if (s[i] == 'x' || s[i] == 'X'){
++i;
break;
}
}
else
++i;
}
n = ;
inhex = YES;
for ( ; inhex == YES; ++i) {
if (s[i] >= '' && s[i] <= '')
hexdigit = s[i] - '';
else if (s[i] >= 'a' && s[i] <= 'f')
hexdigit = s[i] - 'a' + ;
else if (s[i] >= 'A' && s[i] <= 'F')
hexdigit = s[i] - 'A' + ;
else
inhex = NO;
if (inhex == YES)
n = * n + hexdigit;
}
return n;
}

2015.06.16更新  

根据 @garbageMan 的建议:

1.将获取字符数组的代码封装为函数 getstring()

2.修改 htoi() 函数的判断语句,当字符数组不以 “0x” 或 “0X” 开头时也能进行计算

3.简化 htoi() 函数结束循环的标记,去除 inhex 变量

另:

1.将能够获取的字符数组的最大长度定义为常量 MAXC

2.将 htoi() 函数的返回值修改为 double 以容纳更大的结果

完整程序代码如下:

 #include <stdio.h>

 #define MAXC    100        /*    字符数组的最大长度       */

 double htoi(char s[]);
void getstring(char s[]); int main(void)
{
char input[MAXC]; getstring(input);
printf("输入的16进制数转换十进制数:%.0f\n",htoi(input));
return ;
} double htoi(char s[])
{
int hexdigit,i;
double n; i=;
while (s[i] != '\0'){
if (s[i] == '') {
++i;
if (s[i] == 'x' || s[i] == 'X'){
++i;
break;
}
else
break; /* 0之后不是x或X的话则从0开始计算 */
}
/* 是以下符合十六进制的字符则从其开始计算 */
else if((s[i] >= '' && s[i] <= '')
|| (s[i] >= 'a' && s[i] <= 'f')
|| (s[i] >= 'A' && s[i] <= 'F'))
break;
else /* 非十六进制字符,跳过 */
i++;
}
n = 0.0;
for ( ; ; ++i) {
if (s[i] >= '' && s[i] <= '')
hexdigit = s[i] - '';
else if (s[i] >= 'a' && s[i] <= 'f')
hexdigit = s[i] - 'a' + ;
else if (s[i] >= 'A' && s[i] <= 'F')
hexdigit = s[i] - 'A' + ;
else
break;
n = * n + hexdigit;
}
return n;
} /* 获取字符数组 */
void getstring(char s[])
{
int c,i; for ( i = ; i < MAXC- && ((c = getchar()) != EOF); ++i)
s[i] = c;
s[i] = '\0';
}

扩展《C程序设计语言》练习2-3程序通用性的更多相关文章

  1. python程序设计语言笔记 第一部分 程序设计基础

    1.1.1中央处理器(CPU) cpu是计算机的大脑,它从内存中获取指令然后执行这些指令,CPU通常由控制单元和逻辑单元组成. 控制单元用来控制和协调除cpu之外的其他组件的动作. 算数单元用来完成数 ...

  2. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  3. Oberon程序设计语言简介

    Oberon奥伯龙是一种通用编程语言,也是一种同名操作系统(由Oberon语言开发,且参考过贝尔实验室的新一代网络操作系统Plan9),是由原Pascal程序设计语言的发明者Niklaus Wirth ...

  4. awk程序设计语言之-awk基础

    awk程序设计语言之-awk基础 http://man.linuxde.net/ 常用工具命令之awk命令 awk是一种编程语言,用于在Linux/Unix下对文本和数据处理.数据可以来自标准输入(s ...

  5. c++学习书籍推荐《C++程序设计语言(特别版)》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <C++程序设计语言(特别版•十周年中文纪念版)>编辑推荐:十周年纪念版,体味C++语言的精妙与魅力,享受与大师的心灵对话.1979年,Biarn ...

  6. java语言实现对程序设计语言源文件统计字符数、单词数、行数及其他拓展功。

    本次作业Github项目地址:https://github.com/YiChenglong2018/WordCount 一.项目简介 本项目的需求可以概括为:对程序设计语言源文件统计字符数.单词数.行 ...

  7. 操作系统和程序设计语言的API使用的字符编码分析

     1.Java的运行环境中,String是什么编码? 使用java做程序设计语言,字符编码是和jvm相关的,和操作系统无关. java默认的编码是jvm在安装的时候就确定了的,它是根据你的系统的环境确 ...

  8. 利用Scala语言开发Spark应用程序

    Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...

  9. 【HTML/XML 8】XSL,可扩展样式表语言

    导读:上篇博客说了在XML文档中实现表现形式的一种形式:CSS层叠样式表,本篇博客将接着说明其另一种实现方式XSL,并将分析XSL和CSS之间的 关系. 一.XSL简介 XSL(eXtensible ...

随机推荐

  1. 《算法问题实战策略》-chaper8-动态规划法

    Q1:偶尔在电视上看到一些被称为“神童”的孩子们背诵小数点以后几万位的圆周率.背诵这么长的数字,可利用分割数字的方法.我们用这种方法将数字按照位数不等的大小分割后再背诵. 分割形式如下: 所有数字都相 ...

  2. Solr与mmseg4J的整合

    Solr与mmseg4j部署   一. solr安装 1. 下载solr http://www.apache.org/dyn/closer.cgi/lucene/solr/ 2. apache-sol ...

  3. Java学习的随笔(3)接口

    首先是一段<Java编程思想>中,对接口的解释:“interface这个关键字产生一个完全抽象的类,它根本就没有提供任何具体的实现.它允许创建者确定方法名.参数列表.返回类型,但是没有任何 ...

  4. 【微信公众号】将微信公众号消息里的FromUserName即OpenID转成UnionID

    最近在调试微信公众号开发者模式,处理公众号消息,收到如下回调消息内容 <xml><ToUserName><![CDATA[gh_29********21]]>< ...

  5. Project Euler problem 62

    题目的大意很简单 做法的话. 我们就枚举1~10000的数的立方, 然后把这个立方中的有序重新排列,生成一个字符串s, 然后对于那些符合题目要求的肯定是生成同一个字符串的. 然后就可以用map来搞了 ...

  6. 在VisualStudio 2012中通过SmallSharp压缩js及修改web.config

    在项目中加入一个targets文件,取名my.build.targets 在targets文件中加入内容: <?xml version="1.0" encoding=&quo ...

  7. 线程技术 ☞ Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  8. 转载:C# 之泛型详解

    本文原地址:http://www.blogjava.net/Jack2007/archive/2008/05/05/198566.html.感谢博主分享! 什么是泛型 我们在编写程序时,经常遇到两个模 ...

  9. oracle 自治事物 -- autonomous transaction

    一 使用规则 : 在begin 之前申明  : PRAGMA AUTONOMOUS_TRANSACTION; 二 使用理解:autonomous transaction 是一个独立的事务,这一点是理解 ...

  10. MySQL存储过程(一)

    1.1 CREATE  PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...