p/x num 以16进制输出
p/a num 以16进制输出
p/t num 以2进制输出
p/c num 以字符形式输出
p/o num 以8进制输出
#include "dcclientcache.h"
#define CACHE_MAX_SIZE 32*1024
typedef struct _SDCRing
{
char buf[CACHE_MAX_SIZE];
uint32_t size;
uint32_t in;
uint32_t out;
uint32_t send;
}SDCRing;
SDCRing xDCRing;
void vRingInit()
{
memset(xDCRing.buf, 0, sizeof(xDCRing.buf));
xDCRing.size = CACHE_MAX_SIZE;
xDCRing.in = 0;
xDCRing.out = 0;
}
uint32_t uiRingPut(char * pcBuf, uint32_t uiLen)
{
if(uiLen > xDCRing.size - xDCRing.in + xDCRing.out)
{
LOG_PRINTF(EWarn, DCClient, "Cache left space in no enough.\n");
return 0;
}
uint32_t uil;
uiLen = min(uiLen, xDCRing.size - xDCRing.in + xDCRing.out);
uil = min(uiLen, xDCRing.size - (xDCRing.in & (xDCRing.size - 1)));
memcpy(xDCRing.buf + (xDCRing.in & (xDCRing.size - 1)), pcBuf, uil);
memcpy(xDCRing.buf, pcBuf + uil, uiLen - uil);
xDCRing.in += uiLen;
return uiLen;
}
uint32_t uiRingGetSend(char * pcBuf, uint32_t uiLen)
{
uint32_t uil;
uiLen = min(uiLen, xDCRing.in - xDCRing.send);
uil = min(uiLen, xDCRing.size - (xDCRing.send & (xDCRing.size - 1)));
memcpy(pcBuf, xDCRing.buf + (xDCRing.send & (xDCRing.size - 1)), uil);
memcpy(pcBuf + uil, xDCRing.buf, uiLen - uil);
xDCRing.send += uiLen;
return uiLen;
}
uint32_t uiRingGetOut(char * pcBuf, uint32_t uiLen)
{
uint32_t uil;
uiLen = min(uiLen, xDCRing.in - xDCRing.out);
uil = min(uiLen, xDCRing.size - (xDCRing.out & (xDCRing.size - 1)));
memcpy(pcBuf, xDCRing.buf + (xDCRing.out & (xDCRing.size - 1)), uil);
memcpy(pcBuf + uil, xDCRing.buf, uiLen - uil);
return uiLen;
}
uint32_t uiRingDel(uint32_t uiLen)
{
uiLen = min(uiLen, xDCRing.in - xDCRing.out);
xDCRing.out += uiLen;
return uiLen;
}
void vRingInitSend()
{
xDCRing.send = xDCRing.out;
}
#include "dcclientcodec.h"
int32_t
iEncode8(uint8_t ucValue, char ** ppcBuf, uint16_t * pusEncodeLen)
{
if(NULL == ppcBuf || NULL == *ppcBuf || NULL == pusEncodeLen) {
return EXIT_FAILURE;
}
(*ppcBuf)[0] = ucValue;
*ppcBuf += sizeof(uint8_t);
*pusEncodeLen += sizeof(uint8_t);
return EXIT_SUCCESS;
}
int32_t
iDecode8(uint8_t * pucValue, char ** ppcMsg, uint16_t * pusMsgLen)
{
if(NULL == pucValue || NULL == ppcMsg || NULL == *ppcMsg ||
NULL == pusMsgLen || *pusMsgLen < sizeof(uint8_t))
{
return EXIT_FAILURE;
}
pucValue[0] = (*ppcMsg)[0];
*ppcMsg += sizeof(uint8_t);
*pusMsgLen -= sizeof(uint8_t);
return EXIT_SUCCESS;
}
int32_t
iEncode16(uint16_t usValue, char ** ppcBuf, uint16_t * pusEncodeLen)
{
if(NULL == ppcBuf || NULL == *ppcBuf || NULL == pusEncodeLen) {
return EXIT_FAILURE;
}
char * pcValue = (char*)&usValue;
#if IS_BIG_ENDIAN
(*ppcBuf)[0] = pcValue[0];
(*ppcBuf)[1] = pcValue[1];
#else
(*ppcBuf)[1] = pcValue[0];
(*ppcBuf)[0] = pcValue[1];
#endif
*ppcBuf += sizeof(uint16_t);
*pusEncodeLen += sizeof(uint16_t);
return EXIT_SUCCESS;
}
int32_t
iDecode16(uint16_t * pusValue, char ** ppcMsg, uint16_t * pusMsgLen)
{
if(NULL == pusValue || NULL == ppcMsg || NULL == *ppcMsg ||
NULL == pusMsgLen || *pusMsgLen < sizeof(uint16_t))
{
return EXIT_FAILURE;
}
char * pcValue = (char*)pusValue;
#if IS_BIG_ENDIAN
pcValue[0] = (*ppcMsg)[0];
pcValue[1] = (*ppcMsg)[1];
#else
pcValue[1] = (*ppcMsg)[0];
pcValue[0] = (*ppcMsg)[1];
#endif
*ppcMsg += sizeof(uint16_t);
*pusMsgLen -= sizeof(uint16_t);
return EXIT_SUCCESS;
}
int32_t
iEncode32(uint32_t uiValue, char ** ppcBuf, uint16_t * pusEncodeLen)
{
if(NULL == ppcBuf || NULL == *ppcBuf || NULL == pusEncodeLen) {
return EXIT_FAILURE;
}
char * pcValue = (char*)&uiValue;
#if IS_BIG_ENDIAN
(*ppcBuf)[0] = pcValue[0];
(*ppcBuf)[1] = pcValue[1];
(*ppcBuf)[2] = pcValue[2];
(*ppcBuf)[3] = pcValue[3];
#else
(*ppcBuf)[3] = pcValue[0];
(*ppcBuf)[2] = pcValue[1];
(*ppcBuf)[1] = pcValue[2];
(*ppcBuf)[0] = pcValue[3];
#endif
*ppcBuf += sizeof(uint32_t);
*pusEncodeLen += sizeof(uint32_t);
return EXIT_SUCCESS;
}
int32_t
iDecode32(uint32_t * puiValue, char ** ppcMsg, uint16_t * pusMsgLen)
{
if(NULL == puiValue || NULL == ppcMsg || NULL == *ppcMsg ||
NULL == pusMsgLen || *pusMsgLen < sizeof(uint32_t))
{
return EXIT_FAILURE;
}
char * pcValue = (char*)puiValue;
#if IS_BIG_ENDIAN
pcValue[0] = (*ppcMsg)[0];
pcValue[1] = (*ppcMsg)[1];
pcValue[2] = (*ppcMsg)[2];
pcValue[3] = (*ppcMsg)[3];
#else
pcValue[3] = (*ppcMsg)[0];
pcValue[2] = (*ppcMsg)[1];
pcValue[1] = (*ppcMsg)[2];
pcValue[0] = (*ppcMsg)[3];
#endif
*ppcMsg += sizeof(uint32_t);
*pusMsgLen -= sizeof(uint32_t);
return EXIT_SUCCESS;
}
int32_t
iEncode64(uint64_t ullValue, char ** ppcBuf, uint16_t * pusEncodeLen)
{
if(NULL == ppcBuf || NULL == *ppcBuf || NULL == pusEncodeLen) {
return EXIT_FAILURE;
}
char * pcValue = (char*)&ullValue;
#if IS_BIG_ENDIAN
memcpy(*ppcBuf, pcValue, sizeof(uint64_t));
#else
(*ppcBuf)[7] = pcValue[0];
(*ppcBuf)[6] = pcValue[1];
(*ppcBuf)[5] = pcValue[2];
(*ppcBuf)[4] = pcValue[3];
(*ppcBuf)[3] = pcValue[4];
(*ppcBuf)[2] = pcValue[5];
(*ppcBuf)[1] = pcValue[6];
(*ppcBuf)[0] = pcValue[7];
#endif
*ppcBuf += sizeof(uint64_t);
*pusEncodeLen += sizeof(uint64_t);
return EXIT_SUCCESS;
}
int32_t
iDecode64(uint64_t * pullValue, char ** ppcMsg, uint16_t * pusMsgLen)
{
if(NULL == pullValue || NULL == ppcMsg || NULL == *ppcMsg ||
NULL == pusMsgLen || *pusMsgLen < sizeof(uint64_t))
{
return EXIT_FAILURE;
}
char * pcValue = (char*)pullValue;
#if IS_BIG_ENDIAN
memcpy(pcValue, *ppcMsg, sizeof(uint64_t));
#else
pcValue[7] = (*ppcMsg)[0];
pcValue[6] = (*ppcMsg)[1];
pcValue[5] = (*ppcMsg)[2];
pcValue[4] = (*ppcMsg)[3];
pcValue[3] = (*ppcMsg)[4];
pcValue[2] = (*ppcMsg)[5];
pcValue[1] = (*ppcMsg)[6];
pcValue[0] = (*ppcMsg)[7];
#endif
*ppcMsg += sizeof(uint64_t);
*pusMsgLen -= sizeof(uint64_t);
return EXIT_SUCCESS;
}
int32_t iEncodeMsgHeader(const SDCMsgHeader * pxMsgHeader, char ** ppcBuf, uint16_t * pusEncodeLen)
{
if(NULL == pxMsgHeader || NULL == ppcBuf || NULL == *ppcBuf || NULL == pusEncodeLen)
{
return EXIT_FAILURE;
}
if(iEncode8(pxMsgHeader->ucMsgType, ppcBuf, pusEncodeLen) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
if(iEncode16(pxMsgHeader->usMsgLen, ppcBuf, pusEncodeLen) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int32_t iDecodeMsgHeader(SDCMsgHeader * pxMsgHeader, char ** ppcMsg, uint16_t * pusMsgLen)
{
if(NULL == pxMsgHeader || NULL == ppcMsg || NULL == *ppcMsg ||
NULL == pusMsgLen || *pusMsgLen < DC_MSG_HEADER_LEN)
{
return EXIT_FAILURE;
}
if(iDecode8(&pxMsgHeader->ucMsgType, ppcMsg, pusMsgLen) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
if(iDecode16(&pxMsgHeader->usMsgLen, ppcMsg, pusMsgLen) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
#ifndef DCCLIENT_CODEC_H
#define DCCLIENT_CODEC_H
#include "dcclientpublic.h"
int32_t iEncode8(uint8_t ucValue, char ** ppcBuf, uint16_t * pusEncodeLen);
int32_t iDecode8(uint8_t * pucValue, char ** ppcMsg, uint16_t * pusMsgLen);
int32_t iEncode16(uint16_t usValue, char ** ppcBuf, uint16_t * pusEncodeLen);
int32_t iDecode16(uint16_t * pusValue, char ** ppcMsg, uint16_t * pusMsgLen);
int32_t iEncode32(uint32_t uiValue, char ** ppcBuf, uint16_t * pusEncodeLen);
int32_t iDecode32(uint32_t * puiValue, char ** ppcMsg, uint16_t * pusMsgLen);
int32_t iEncode64(uint64_t ullValue, char ** ppcBuf, uint16_t * pusEncodeLen);
int32_t iDecode64(uint64_t * pullValue, char ** ppcMsg, uint16_t * pusMsgLen);
/*
Example:
pcSendBuf = acSendBuf;
usEncodeLen = 0;
iRet = iEncodeMsgHeader(&xMsgHeader, &pcSendBuf, &usEncodeLen);
after Encode, usEncodeLen is the current data's length.
*/
int32_t iEncodeMsgHeader(const SDCMsgHeader * pxMsgHeader, char ** ppcBuf, uint16_t * pusEncodeLen);
/*
Example:
char * pcRecvBuf = acRecvBuf;
usRecvBufLen: is the current data's length.
iRet = iDecodeMsgHeader(&xMsgHeader, &pcRecvBuf, &usRecvBufLen);
after Decode, usEncodeLen is zero.
*/
int32_t iDecodeMsgHeader(SDCMsgHeader * pxMsgHeader, char ** ppcMsg, uint16_t * pusMsgLen);
#endif
0x12345678
Big-Endian:
低地址——->高地址
12 34 56 78
<br >
Little-Endian:
低地址——->高地址
78 56 34 12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void vEndianTester()
{
union endian_tester{
unsigned int m_int;
unsigned char m_byte[4];
};
endian_tester test;
test.m_int = 0x0a0b0c0d;
if(test.m_byte[0] == 0x0a) {
printf("Big-endian\n");
} else {
printf("Little-endian\n"); //输出
}
}
int main()
{
vEndianTester();
unsigned int uiNum = 0x12345678;
char acBufBig[BUFSIZ] = {0};
char acBufLittle[BUFSIZ] = {0};
memcpy(acBufBig, (char*)&uiNum, sizeof(unsigned int));
printf("acBufBig: %x %x %x %x\n", acBufBig[0], acBufBig[1], acBufBig[2], acBufBig[3]); //78 56 34 12
*(unsigned int*)acBufLittle = uiNum;
printf("acBufLittle: %x %x %x %x\n", acBufLittle[0], acBufLittle[1], acBufLittle[2], acBufLittle[3]); //78 56 34 12
char * pc = (char*)&uiNum;
printf("pc: %x %x %x %x\n", pc[0], pc[1], pc[2], pc[3]); //78 56 34 12
char acLittle2[BUFSIZ] = {0};
acLittle2[0] = pc[3];
acLittle2[1] = pc[2];
acLittle2[2] = pc[1];
acLittle2[3] = pc[0];
printf("acLittle2: %x %x %x %x\n", acLittle2[0], acLittle2[1], acLittle2[2], acLittle2[3]); // 12 34 56 78
return 0;
}
struct book {
char title[MAXTITLE];
char author[MAXAUTL];
float value;
} library;
struct book mybook = {
"The Private and the Pamsel",
"Renee Vivotte",
1.95
};
如果初始化一个具有静态存储时期的结构,初始化项目列表中的值必须是常量表达式。
如果存储时期是自动的,列表中的值就不必是常量了。
&mybook.float
因为点拥有比&更高的优先级,因此这个表达式和 &(mybook.float) 一样。
把结构作为参数传递。
把指向结构的指针作为参数传递。
还可以将结构体成员作为参数传递给函数。
C 允许把一个结构赋值给另一个结构,即使有一个成员是数组也一样可以。
只要结构体中没有指针,就可以直接用等号赋值。
文件视图
二进制视图
文本文件
二进制文件
通常,对于文本文件使用文本视图,对于二进制文件使用二进制视图。
但是,您也可以使用任一视图处理任一文件。
MS-DOS 文本文件用回车符和换行符的组合 \r\n 来表示结尾。
Macintosh 文本文件只使用一个回车符 \r 来表示结尾。
C 程序使用一个 \n 表示结尾。
如果C程序以文本视图模式处理一个MS-DOS文本文件,在读取文件时它会 将 \r\n 转换为 \n ,在写入文件时将 \n 转换为 \r\n 。
而使用二进制视图,程序将会看到文件中的 \r 和 \n 字符,没有任何映射发生。
UNIX仅采用一种文件结构,所以这两种视图在UNIX实现中就是相同的。
低级I/O:使用操作系统提供的基本I/O服务。
标准高级I/O:使用标准的C库函数包和stdio.h头文件的定义。
C 程序自动帮我们打开3个文件:标准输入,标准输出和标准错误输出。
标准I/O包相对于低级I/O有两点优势:
标准I/O包中有很多专用的函数。
对输入和输出进行了缓冲。
“r” 打开一个文本文件,可以读取文件
“w” 打开一个文本文件,可以写入文件,先将文件的长度截为零。如果该文件不存在则先创建之。
“a” 打开一个文本文件,可以写入文件,向已有文件的尾部追加内容。如果该文件不存在则先创建之。
“r+” 打开一个文本文件,可以进行更新,也可以读取和写入文件。如果该文件不存在,则无法打开。
“w+” 打开一个文本文件,可以进行更新(读取和写入),如果该文件存在则先将其长度截为零,如果不存在则先创建之。
“a+” 打开一个文本文件,可以进行更新,向已有的文件尾部追加内容。如果该文件不存在则先创建之。 可以读取整个文件,但写入时只能追加内容。
“rb” “wb” “ab” “ab+” “a+b” “wb+” “w+b” “rb+” “r+b”
与前面的模式相似,只是使用二进制模式而非文本模式打开文件。
对于像 Unix 和 Linux 这样只有一种文件类型的系统,带 b 字母的模式和不带 b 字母的模式是相同的。
Tips:使用任何一种 w 模式打开一个已有的文件,文件内容将被删除,以便程序以一个空文件开始操作。
如果不能打开文件,fopen() 返回空指针。
ch = getchar(); //从标准输入获得一个字符。
ch = getc(fp); //从指针fp指定的文件中获得一个字符。
putc(ch, fpout);
putc(ch, stdout);
putchar();
C 输入函数直到尝试读取超出文件结尾的时候才会检测到文件结尾。
这意味着应该在一次尝试读取之后立即进行文件结尾判断。
int ch;
FILE * fp = fopen("wacky.txt", "r");
while ((ch = getc(fp) != EOF)
{
putchar(ch);
}
SEEK_SET 文件开始
SEEK_cur 文件当前位置
SEEK_END 文件结尾
fseek(fp, 0, SEEK_SET); 文件开始处
fseek(fp, 10, SEEK_SET); 找到文件的第10个字符
fseek(fp, 2, SEEK_cur); 当前位置向前移动2个字节
fseek(fp, 0, SEEK_END); 文件结尾
fseek(fp, -10, SEEK_END); 从文件结尾处退回10个字节