原题出自:《The C Programming Language - Second Edition》一书的练习2-3

编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值。字符串中允许包含的数字包括:0~9、a~f以及A~F。

在做这题时,遇到的问题主要是:如何判断字符数组中的这个十六进制数是正数还是负数,如果是负数,应该如何转换?

通过百度了解我发现十六进制的正负是按其对应的二进制的符号位0 or 1决定;

那么非要转换为二进制处理才行吗?怎么转换?又怎么判断哪个是符号位?

按照答者说的,打开电脑自带计算器看了下:

windows键 + R --> 输入calc,打开 --> Alt + 3(#),选择程序员型

玩了一下这个计算器便发现红圈内的东东:

也就是说,一个16进制数,如果不知道它是用几位的16进制数来表示,就无法判断符号位。

例如,只给你0xFFFF,判断它是正还是负?

看到这么个评论,我才醒悟。

答案是无从知晓

如果它是用一个‘字’表示的,则是 -1;

如果它是用双字表示的,则是正数。

通过一段思考,清扫迷雾。现在我的思路是:

如果给你个字符数组0xF\0或0xFFFFFFFFF\0,C语言中怎么判断它的正负?

先判断那是几位的十六进制数 /* 这样好判断对应的二进制的符号位 */

if 长度 < 位数n

毋庸置疑这是正数;/* 因为在其前补零使其为n位16进制,那二进制符号位必为0 */

if 长度 = 位数n

if 第一位 >= 8    /* 为什么是 >= 8 ?; 8(16进) --> 1000(2进)*/

为负数;

else

为正数;

清除了以上这些迷雾,写代码就不难了:#include

#include

#include

enum inputstat {NO, YES};    /* 输入有误时,normal = NO,不输出错误的num*/

enum inputstat normal = YES;

int main()

{

char ox[30];

long int num;

long int htoi(char s[]);/* 如果数组是包含0x或0X的十六进制数,函数将返回对应的整型值;否则输出错误提示*/

gets(ox);

num = htoi(ox);

if (normal == YES)

printf("%ld\n", num);

return 0;

}

/* 含一个无小数部分的十六进制数的数组转换为整型值;需要选择16进制数的长度*/

long int htoi(char s[])

{

int i, j, k, temp, twori, tbit, bit_16;

long int num;

/* i为数组s[]当前位置;

* j为16(2)进制的位数减一;

* k用于操作时标记每位十六进制数对应的四位二进制数之一;

* temp为0~9和a~f/A~F对应的十进制数;

* twori为二进制从左往右的位数;

* tbit标记着二进制数最小位;

* bit_16表示十六进制数的位数;

*/

int two[64];/* 用于存放二进制的数组,并对其进行操作*/

printf("请选择十六进制数 %s 的占用内存长度:\n  1、单字节\t\t2、字\n  3、双字\t\t4、四字\n", s);

bit_16 = pow(2, getchar() - '0');

if (bit_16 == 1 || bit_16 > 16) {

printf("error: 选择的长度错误!\n");

normal = NO;

return 0;

}

j = twori = 0;

num = 0;

i = strlen(s);

if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && i > 2) {/* 判断s[]是否为以0x或0X开头的数组    */

if (i - 2 == bit_16 && (s[2] == '8' || s[2] == '9' || s[2] <= 'a' && s[2] >= 'f' || s[i] >= 'A' && s[i] <= 'F')) {/* 十六进制是否为负数*/

for (i = 2; s[i] != '\0'; ++i) {/* 此循环结构将负数转为二进制反码,循环结束后,i为16进制数的位数 + 1(标记着'\0'),twori则标记着二进制数组的最小位 */

if (s[i] >= '0' && s[i] <= '9')

temp = s[i] - '0';

else if (s[i] >= 'a' && s[i] <= 'f')

temp = s[i] - 'a' + 10;

else if (s[i] >= 'A' && s[i] <= 'F')

temp = s[i] - 'A' + 10;

else {

printf("error: Contains illegal characters");

normal = NO;

return 0;

}

for (k = 0; k

two[twori++] = temp / (8 / pow(2, k));

temp = temp % (8 / (int)(pow(2, k)));

}

}

two[twori] = '\0';

tbit = --twori;

/* 下面进行二进制减一操作,以获得补码*/

if (two[twori] == 1)

two[twori] = 0;

else if (two[twori] == 0) {

two[twori] = 1;

for (--twori; two[twori] == 0; --twori)

two[twori] = 1;

two[twori] = 0;

}

/* 按位取反操作,以获得原码*/

for (k = 0; two[k] != '\0'; ++k)

if (two[k] == 1)

two[k] = 0;

else if (two[k] == 0)

two[k] = 1;

/* 把二进制原码转十进制,以获得十进制数的绝对值*/

j = 0;

for (k = tbit; k >= 0; --k) {

num = num + two[k] * pow(2, j);

j++;

}

/* 将上一步得到的int num乘-1,以获得正确的整型值*/

num = num * (0 - 1);

}

else if (i - 2 <= bit_16) {/* 十六进制是否为正数*/

for (--i; i >= 2; --i) {

if (s[i] >= '0' && s[i] <= '9')

temp = s[i] - 48;

else if (s[i] >= 'a' && s[i] <= 'f')

temp = s[i] - 97 + 10;

else if (s[i] >= 'A' && s[i] <= 'F')

temp = s[i] - 65 + 10;

else {

printf("error: Contains illegal characters");

normal = NO;

return 0;

}

num = num + temp * pow(16, j);

++j;

}

}

else {

printf("error: 选择的长度错误!\n");

normal = NO;

return 0;

}

}

else if(i > 2) {

printf("error: Chars not beginning with '0x' or '0X'\n");

normal = NO;

return 0;

} else {

printf("error: Chars just have '0x' or '0X'\n");

normal = NO;

return 0;

}

return num;

}

程序还有一些问题,有些数据检测错误例如0XFFFFFC87;待续

c语言字符串怎么转为正数,把字符串转换为与之等价的整型值相关推荐

  1. 将C语言的字符串转为OC的字符串

    <pre name="code" class="objc">3.C语言和OC结合题目 从控制台输入用户名和密码, 然后 判断输入的用户名是否是@&q ...

  2. 字符串转内存c语言,【一起学C】C语言面试题必考:字符串操作函数,内存操作函数实现...

    本帖最后由 奉聪 于 2017-1-25 14:54 编辑 *******前言******* 我数一下,我发了几个帖子,1.2.3? 哈哈哈,没几个哈,感谢吾爱,让我学到了很多,乐于分享,共同进步! ...

  3. c语言整型变量转字符串,将整型变量转化为字符串

    C++中如何将整型变量转换为字符串 int i=1; string str="结果:"; string str2; str2=str+i; cout< C语言中将整形变量转换 ...

  4. R语言str_subset函数和str_which函数:str_subset函数提取字符串向量中所有包含匹配字符的字符串、str_which函数返回字符串向量中所有包含匹配字符的位置(索引)

    R语言str_subset函数和str_which函数:str_subset函数提取字符串向量中所有包含匹配字符的字符串.str_which函数返回字符串向量中所有包含匹配字符的位置(索引) 目录

  5. R语言stringr包str_detect函数检测字符串中模式存在与否实战

    R语言stringr包str_detect函数检测字符串中模式存在与否实战 目录 R语言stringr包str_detect函数检测字符串中模式存在与否实战 #导入stringr包

  6. R语言eval函数评估表达式或者字符串实战

    R语言eval函数评估表达式或者字符串实战 目录 R语言eval函数评估表达式或者字符串实战 #基本语法 #eval函数评估表达式

  7. Swift3.0语言教程查找字符集和子字符串

    Swift3.0语言教程查找字符集和子字符串 Swift3.0语言教程查找字符集和子字符串,在字符串中当字符内容很多时,我们就需要使用到查找字符集或者子字符串的方法.以下我们将讲解3种查找字符集和子字 ...

  8. mysql将字符串字段转为数字排序或比大小

    SELECT * FROM Student WHERE 1 = 1 ORDER BY -ID DESC ; SELECT * FROM Student WHERE 1 = 1 ORDER BY (ID ...

  9. jq js json 转字符串_JQuery如何把JSON字符串转为JSON对象

    本文介绍JQuery如何把JSON字符串转为JSON对象. HTML代码 下面的HTML代码实现JQuery把JSON字符串转为JSON对象. Name: Age: City: Country: va ...

最新文章

  1. 界面怎么使用pip_从零开始学Python——10Pyinstaller的使用
  2. 董彬教授:用深度神经网络学习偏微分方程及其数值求解的离散格式
  3. Eclipse europa 更新时 Error retrieving feature.xml. [error in opening zip file]
  4. python医学科研中能做什么-一个博士生接受怎样的训练是完整、全面的科研训练?...
  5. 数据意识上的“代沟”
  6. 【深度学习】揭秘2021抖音和快手APP图像修复背后的核心技术,毫无ps痕迹
  7. 限制不能使用最近三次的历史密码
  8. 使用protostuff进行序列化
  9. bootstrap-multiselect样式修改
  10. 安装fastDFS的依赖包fdfs_client报错解决方法
  11. 【优化预测】基于matlab天牛须算法优化ELMAN神经网络预测【含Matlab源码 1375期】
  12. 【数字图像处理系列二】基本概念:亮度、对比度、饱和度、锐化、分辨率
  13. pymc3学生成绩分析和预测(补充+翻译)
  14. 怎么查看XP系统是32位还是64位
  15. DDIA - 读书笔记
  16. 广州史帝奇轨道环幕影院的优势、特点、应用领域
  17. wo-27s管理员账户和密码_某数据监测与分析系统可被撞库出登录密码
  18. 阿昌教你使用谷歌guava工具包---集合包
  19. 数据太大,记事本打不开怎么办?
  20. SpringMVC学习系列(6) 之 数据验证

热门文章

  1. 简述python程序结构_Python-选择结构程序设计
  2. 如何HTML中输入正确格式,以HTML格式输入样式
  3. Android可滑动画板,Android 利用 Canvas 画画板
  4. pwm一个时间单位_PTO PWM要点
  5. matlab thetal,基於matlab的車道和車道線檢測樣例
  6. java中json对象去重复_如何忽略Java中JSON对象的多个属性?
  7. python百度知道_用Python写的一个【百度知道】自动点赞
  8. mysql随机查询多条记录表_MySQL 随机查询表中N条记录
  9. ConstantSourceNode
  10. 数据可视化之多属性(字段)