字符流与字节流的相互转换原理及代码(Linux C)
文章目录
- 一. 两者的区别
- 二. 还需要了解
- 三. 字节流转字符流实现
- 三. 字符流转字节流实现
- 四. 测试程序
- 4.1 头文件
- 4.2 用于测试的程序
- 4.2 简单写一个makefile
- 4.3 运行
我们在做项目时,常常会遇到将字节流的数据转成字符流,或者将字符流的数据转为字节流,例如最近做的一个项目,其中一个模块是使用移远的EC20 4G模块通过串口编程实现中英文短信的发送与接收,其中:
- 在中文短信的发送时,要进行PDU的编码,其中包括了utf-8转unicode的处理,获取到的是字节流的unicode编码,但PDU格式是要求给串口发送字符流的数据,所以会使用的字节流转换为字符流的相关操作
- 在获取模块接收到的短信时,获取到的是一个字符流形式的unicode编码,编码我们是读不出来任何短信内容的,所以这是需要将unicode编码转为utf-8的编码才能打印并获取到短信内容,就需要在转码之前,将字符流的unicode编码转为字节流,因为字符流其本质是保存了相应字符的ASCII码值,并不能用来进行转码
下面就来看是是转换的原理和代码吧~
一. 两者的区别
字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
字节流默认不使用缓冲区;字符流使用缓冲区。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。
二. 还需要了解
ASCII编码对照表
通过ASCII码对照表我们可以知道,要想获取到数值对应字符(如0x0a 对应的是字符‘0’ 和字符 ‘a’),以及反过来的字符对应的数值(如字符‘9’的数值是0x39),需要进行相关的加减法,还需要注意的是,字符’0’~‘9’后是7个符号,之后才是字符’A’~‘Z’,
三. 字节流转字符流实现
每个字节流数据都对应了两个字符就数据,如0xfe 对应了字符 ’ f ‘,’ e '.
/* * 函数名:void Hex2Str(const char *source, int source_len, char *dest)* 功能 :将字节流的数据转为字符流形式* 参数 :source - 字节流数据 source_len - 长度 dest - 用来保存转换后的字符流数据* 返回值:无* * */
void Hex2Str(const char *source, int source_len, char *dest)
{int i;unsigned char HighByte; //保存高位unsigned char LowByte; //保存低位for(i=0; i<source_len; i++){HighByte = source[i] >> 4; //获取一个字节数据的高4位LowByte = source[i] & 0x0f; //获取一个字节数据的低4位HighByte += 0x30; //得到对应的字符,若是字母还需要跳过7个符号if(HighByte <= 0x39) //数字dest[i*2] = HighByte;else //字母dest[i*2] = HighByte + 0x07; //得到字符后保存到对应位置LowByte += 0x30;if(LowByte <= 0x39)dest[i*2+1] = LowByte;elsedest[i*2+1] = LowByte + 0x07;}return;
}
三. 字符流转字节流实现
字符流的数据中,两个字符转为一个字节流数据,如字符串"1afd3c",可转为数值0x1a,0xfd,0x3c
/* * 函数名:void Str2Hex(const char *source,int source_len,char *dest)* 功能 :将字符流的数据转为字节流形式* 参数 :source - 字符流数据 source_len - 长度 dest - 用来保存转换后的字节流数据* 返回值:无** */
void Str2Hex(const char *source,int source_len,char *dest)
{int i;unsigned char HighByte; //保存高位unsigned char LowByte; //保存低位for(i=0; i<source_len; i++){HighByte = toupper(source[i*2]); //如果遇到小写,则转为大写处理LowByte = toupper(source[i*2+1]);if(HighByte <= 0x39) //0x39对应字符'9',这里表示是数字HighByte -= 0x30;else //否则为字母,需要跳过7个符号HighByte -= 0x37;if(LowByte <= 0x39)LowByte -= 0x30;elseLowByte -= 0x37;/** 假设字符串"3c"* 则 HighByte = 0x03,二进制为 0000 0011 * LowByte = 0x0c,二进制为 0000 1100* * HighByte << 4 = 0011 0000* HighByte | LowByte :* * 0011 0000* 0000 1100* -------------* 0011 1100** 即 0x3c* **/dest[i] = (HighByte << 4) | LowByte; }
}
四. 测试程序
4.1 头文件
/********************************************************************************* Copyright: (C) 2020 LuXiaoyang<920916829@qq.com>* All rights reserved.** Filename: String_Bytes.h* Description: This head file ** Version: 1.0.0(30/07/20)* Author: LuXiaoyang <920916829@qq.com>* ChangeLog: 1, Release initial version on "30/07/20 16:58:45"* ********************************************************************************/
#ifndef _STRING_BYTES_H_
#define _STRING_BYTES_H_#include <stdio.h>
#include <string.h>
#include <ctype.h>#define BUFLENGTH 32/* 字节流转字符流 */
void Hex2Str(const char *source, int source_len, char *dest);/* 字符流转字节流 */
void Str2Hex(const char *source,int source_len,char *dest);#endif /* ----- #ifndef _STRING_BYTES_H_ ----- */
4.2 用于测试的程序
/********************************************************************************** Copyright: (C) 2020 LuXiaoyang<920916829@qq.com>* All rights reserved.** Filename: main.c* Description: This file a* * Version: 1.0.0(30/07/20)* Author: LuXiaoyang <920916829@qq.com>* ChangeLog: 1, Release initial version on "30/07/20 17:03:36"* ********************************************************************************/
#include "String_Bytes.h"int main(int argc, char *argv[])
{int i;char String[BUFLENGTH] = "3c5d6cfecd4c";char Hexstring[BUFLENGTH] = {0};char String2[BUFLENGTH] = {0};Str2Hex(String,strlen(String),Hexstring);for(i=0; i < strlen(String)/2; i++){printf("0x%02x ",Hexstring[i]);}printf("\n");Hex2Str(Hexstring,strlen(String)/2,String2);printf("%s\n",String2);return 0;}
4.2 简单写一个makefile
CC = gccmain: main.c String_Bytes.o$(CC) main.c String_Bytes.o -o main String_Bytes.o: String_Bytes.c$(CC) -c String_Bytes.cclean:rm *.o main
4.3 运行
像这样封装好函数,以后要用到的就直接把头文件c文件拷贝就可以直接调用函数了,也可以和其他自定义的字符串相关函数封装生成一个动态库使用.
字符流与字节流的相互转换原理及代码(Linux C)相关推荐
- 字符流和字节流的原理及区别
参考:https://www.cnblogs.com/absfree/p/5415092.html 1. 流的概念 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不 ...
- 字符流与字节流的相互转换
1:字节流转换成字符流: 字节流转换成字节流需要使用InputStreamReader构造方法: InputStreamReader( InputStream in) 2:字符流转换成字节流: 输出字 ...
- 字符流和字节流效率问题及原理,以及开发中使用
https://www.cnblogs.com/DONGb/p/7844123.html 先来看一下流的概念: 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据 ...
- java中字符流 字节流_理解Java中字符流与字节流的区别
1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可 ...
- java字符流和字节流的区别_java字符流与字节流的区别是什么
java中字符流与字节流的区别: 1.字节流操作的基本单元为字节:字符流操作的基本单元为Unicode码元. 2.字节流默认不使用缓冲区:字符流使用缓冲区. 3.字节流通常用于处理二进制数据,实际上它 ...
- JAVA I/O流 字符流和字节流、节点流和处理流(包装流、过滤流)、缓冲流
JAVA IO流 一.相关概念 1.分类: 区别和联系 代码 嵌套的IO流关闭的问题 一.相关概念 I/O流: Input/Output Stream,文件输入输出流. 1.分类: 输入流 和 输出流 ...
- 01-21 IO流(字符流与字节流)
IO流(字符流与字节流) 今日内容介绍 标准输入流 & 转换流 & 打印流 对象操作流 Properties集合 第1章标准输入流 & 转换流 & 打印流 ...
- 笔记整理5----Java语言高级(五--完结)21 字符流与字节流+22 多线程+23 网络编程
21 字符流与字节流+22 多线程+23 网络编程 第10天 IO流 今日内容介绍 标准输入流 & 转换流 & 打印流 对象操作流 Properties集合 第1章标准输入 ...
- 【Java网络编程与IO流】Java中IO流分为几种?字符流、字节流、缓冲流、输入流、输出流、节点流、处理流
Java网络编程与IO流目录: [Java网络编程与IO流]Java中IO流分为几种?字符流.字节流.缓冲流.输入流.输出流.节点流.处理流 [Java网络编程与IO流]计算机网络常见面试题高频核心考 ...
最新文章
- Hi3516a移植SDL+FreeType+SDL_ttf
- 4.3 IP数据报格式
- Java中通过命令行启动jar包时指定编码
- 日常生活中的法语积累2
- 2.php函数,PHP常用函数总结(2)
- 企业数据化应用的第一步,你需要报表管理平台
- python如何使用geotools_Python pygeotools包_程序模块 - PyPI - Python中文网
- 马云自评英语水平;支付宝推刷脸支付;苹果研发基带芯片 | 极客头条
- 一种定力夹具控制系统
- Javascript第四章参数和返回值基本用法第二课
- swift 将图片资源打包成Bundle
- 为啥OpenStack厂商要参加双态运维大会?
- 拜腾“难”飞:全球化饮鸩止渴?
- dubbo filter原理
- 【雷达与对抗】【2011.07】穿墙超宽带雷达成像
- 博大考神》2006版之Word2003题库版操作提示
- 医学计算机论文,医学图像数据库-外文翻译(计算机论文,医学论文适合)
- python掷骰子猜大小
- 爱奇艺笔试题之成长值计算
- SAP 批量导出客户主数据