c語言大端小端轉換
1. c語言讀寫二進制文件讀取 大小端,該怎麼解
先看下面的代碼,然後我在簡短的解釋一下。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <string>#define nmemb 7/****************************************************Date types(Compiler specific) 數據類型(和編譯器相關)
*****************************************************/typedef unsigned char uint8; /* Unsigned 8 bit quantity */typedef signed char int8; /* Signed 8 bit quantity */typedef unsigned short uint16; /* Unsigned 16 bit quantity */typedef signed short int16; /* Signed 16 bit quantity */typedef unsigned int uint32; /* Unsigned 32 bit quantity */typedef signed int int32; /* Signed 32 bit quantity */typedef float fp32; /* Single precision */
/* floating point */typedef double fp64; /* Double precision */
/* floating point *///int32#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000 ) >> 24) |
(( (uint32)(A) & 0x00ff0000 ) >> 8) |
(( (uint32)(A) & 0x0000ff00 ) << 8) |
(( (uint32)(A) & 0x000000ff ) << 24))//int16#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8 ) |
(( (uint16)(A) & 0x00ff ) << 8))/************************************************************
* Conversion little endian float data to big endian
* *************************************************************/float ReverseFloat(const float inFloat)
{ float retVal; char *floatToConvert = (char*) & inFloat; char *returnFloat = (char*) & retVal; // swap the bytes into a temporary buffer
returnFloat[0] = floatToConvert[3];
returnFloat[1] = floatToConvert[2];
returnFloat[2] = floatToConvert[1];
returnFloat[3] = floatToConvert[0]; return retVal;
}struct matrix
{ int row; int column;
}s[nmemb];void set_s(int j, int x, int y)
{
s[j].row = x;
s[j].column = y;
}bool is_bigendian()
{ int a = 0x1234; char b = *(char *)&a; //b == the Low address part of a
//printf("%c ", b);
if (b == 0x34) { return false;
} return true;
}int main()
{ if (is_bigendian()) { printf("BigEndian ");
} else { printf("LittleEndian ");
}
FILE *fp;
set_s(0, 1, 50);
set_s(1, 1, 80);
set_s(2, 4, 20);
set_s(3, 50, 1);
set_s(4, 80, 2);
set_s(5, 100, 3);
set_s(6, 100, 4); int ans = sizeof(struct matrix); printf("size: %d ", ans); printf("size: %d ", sizeof(s)); if ((fp = fopen("test", "wb")) == NULL) { printf("EROOR "); return 1;
} for (int j = 0; j < nmemb; ++j) { printf("row: %d column: %d ", s[j].row, s[j].column);
}
fwrite(s, sizeof(struct matrix), nmemb, fp); for (int i = 0; i < nmemb; ++i) { float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column); for (int j = 0; j < s[i].row; ++j) { for (int k = 0; k < s[i].column; ++k) {
m[k + j*s[i].column] = k;
}
}
fwrite(m, sizeof(float), s[i].row * s[i].column, fp); free(m);
}
fclose(fp); printf("11 "); /*
printf("%d ", sizeof(float));
FILE *fp;
if ((fp = fopen("test", "rb")) == NULL) {
printf("EROOR ");
return 1;
}
fread(s, sizeof(struct matrix), nmemb, fp);
for (int i = 0; i < nmemb; ++i) {
printf("row: %d column: %d ", s[i].row, s[i].column);
}
for (int i = 0; i < nmemb; ++i) {
float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column);
fread(m, sizeof(float), s[i].row * s[i].column, fp);
for (int j = 0; j < s[i].row; ++j) {
for (int k = 0; k < s[i].column; ++k) {
printf("%lf ", m[k + j*s[i].column]);
}
printf(" ");
}
printf(" ");
free(m);
}
fclose(fp);
*/
return 0;
}
fopen和fclose是很常見的,在這里就不做解釋了。我們來看看fwrite和fread,本來以為這個很麻煩,但是用過之後發現這個二進制文件讀寫才是最簡單的。
size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
fwrite()用來將數據寫入文件流中。
stream為已打開的文件指針
ptr 指向欲寫入的數據地址
寫入的字元數以參數size*nmemb來決定。
size表示寫入一個nmemb的內存大小。
fwrite()會返回實際寫入的nmemb數目。
size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);
fread()用來從文件流中讀取數據。
stream為已打開的文件指針
ptr 指向欲存放讀取進來的數據空間
讀取的字元數以參數size*nmemb來決定
size表示讀取一個nmemb的內存大小。
fread()會返回實際讀取到的nmemb數目,如果此值比參數nmemb 小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生什麼情況。
返回實際讀取到的nmemb數目。
詳情參見上面的代碼。
另外就是大小端的問題了。關於大小端的具體解釋網上有很多,在此不作解釋。參考上面寫的代碼,我判斷了自己機器是大端還是小端,並且實現了int16,int32已經float數據類型的大小端轉換,大端轉小端,在使用相同的代碼一次小端又變成了大端。
PS:float的大小端轉化我之前一直以為寫的是錯的,因為好多數據轉化之後輸出都是0。後來發現可能是與float類型在內存中的存放有關,我們的程序是對的。
2. c語言和java 使用socket通信的時候 數據大小端轉換的問題
大小端轉換就是移位,拼接,用C實現很簡單。
至於解析出問題,可以約定雙方以位元組流進行通信,比如,約定一個浮點數拆成文本,或者一個32位長整拆成四個位元組,先傳送低位元組(或高位元組),約定好以後,兩邊都照做就可以了。
3. unicode大端,小端相互轉化,該怎麼處理
計算機的一個int型數據是用多個位元組表示的,如果在內存中存放時標稱該數據的地址中存放的是數據的最低位元組,就叫小端機,反之把高位元組存放在標稱地址中的則稱為大端機。所以可以定義一個int變數,將其地址強制為char*型地址,檢測該地址中的數
4. C語言讀寫二進制文件讀取 大小端,該怎麼解決
1、二進制文本使用fopen函數的二進制模式「rb」就可以打開。對於程序來說,不管後綴名如何,文件分為兩種類型:文本文件和二進制文件。 C語言里有一系列文件操作函數。區分文本和二進制文件,需要在打開文件時設置不同的控制符mode的變數即可。
5. c語言中小端次序和大端次序的概念和作用
具體概念去網路吧,少年。
不過舉個栗子,short a = 0xF0F0;
假設左側都是物理地址的高地址那麼這個數據儲存,
大端是:0F0F(IBM等)
小端是:F0F0(大部分機器)
作用是,加深理解一些程序的儲存與出錯原因,然後對於位域的整體賦值有較好考慮。
6. C語言測試大小端的問題
大端模式,是指數據的高位元組保存在內存的低地址中,而數據的低位元組保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字元串順序處理:地址由小向大增加,而數據從高位往低位放;
小端模式,是指數據的高位元組保存在內存的高地址中,而數據的低位元組保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和我們的邏輯方法一致。
測試程序:
#include<stdio.h>
intmain(void)
{
inta=0x12345678;
unsignedchar*p=(unsignedchar*)&a;
if(0x78==*p)
{
printf("littleend ");
}
else
{
printf("bigend ");
}
return0;
}