2016-11-21 9 views
3

私はいくつかのchar配列を持っています:char char[8]最初の4つのインデックスには例えば2つのintを含み、最初のintには次の4つのインデックスがあります。char *をいくつかの変数に分割します。

char array[8] = {0,0,0,1,0,0,0,1}; 
int a = array[0-3]; // =1; 
int b = array[4-8]; // =1; 

この配列を2つのint型にキャストする方法はありますか?

は必ずしもint型ではない、他のタイプが存在することができますが、これは唯一のいくつかの例です。サイズは4なり、その後intに、配列の各をキャストします、私は私は2つの文字列に、この配列をコピーすることができます知っている

。しかし、私はこれがうまくないと思うし、クリーンなコードの原則を破る。

+3

... – Charles

+2

あなただけの' int型* 'へ'のchar * 'をキャストすることはできませんエンディアンのために。 –

+3

魔法が欲しいと思うようです。残念ながら、この世界では魔法はありません。変換を行う関数を記述する必要があります。 –

答えて

6

あなたのデータが正しいエンディアンを持っている場合は、あなたとバイトバッファからblitable種類を抽出することができますmemcpy

int8_t array[8] = {0,0,0,1,0,0,0,1}; 
int32_t a, b; 
memcpy(&a, array + 0, sizeof a); 
memcpy(&b, array + 4, sizeof b); 

@Vivekがntohlはエンディアンを正規化するために使用できることが正しいですが、あなたは第二段階として、それをしなければなりません。 strict aliasingに違反するポインタを使用してゲームをプレイしないでください。実際には、配列の例外またはコードの大部分を到達不能として破棄するオプティマイザが未定義の動作につながります。

int8_t array[8] = {0,0,0,1,0,0,0,1}; 
int32_t tmp; 
memcpy(&tmp, array + 0, sizeof tmp); 
int a = ntohl(tmp); 
memcpy(&tmp, array + 4, sizeof tmp); 
int b = ntohl(tmp); 

ほぼすべての最適化コンパイラは、彼らが小さな定数count引数でmemcpyを見たときに関数を呼び出していないために十分にスマートであることに注意してください。

-1

バイト配列をint *にキャストすることができます。逆参照により、4バイトがintとして読み取られます。次に、ntohlを実行して、intのバイトがホストの順番どおりに配置されるようにします。

char array[8] = {0,0,0,1,0,0,0,1}; 

int a = *((int *)array); 
int b = *((int *)&array[4]); 

a = ntohl(a); 
b = ntohl(b); 

リトルエンディアンとビッグエンディアンの両方でaとbを1に設定します。

コンパイラは、厳密なエイリアシングのために設定されている場合は、次のようにmemcpyのは、同じことを達成するために使用することができます

char array[8] = {0,0,0,1,0,0,0,1}; 
int a, b; 

memcpy(&a, array, sizeof(int)); 
memcpy(&b, array+4, sizeof(int)); 

a = ntohl(a); 
b = ntohl(b); 
+1

これはなに? –

+3

これは未定義の動作です。厳密なエイリアシングは 'char * 'を使って' int'にアクセスすることを許します、 'int *'を使って 'char []'にアクセスすることはできません。悪さが続く –

+0

リトルエンディアンシステムで動作します。私はちょうどそれをダブルチェックするためにそれを試しました。 memcpyも同様に使用できます。 – Vivek

1

のは、std::accumulateとしてC++アルゴリズムの少しを使ってみましょう:

#include <numeric> 
#include <iostream> 

int getTotal(const char* value, int start, int end)  
{ 
    return std::accumulate(value + start, value + end, 0, 
          [](int n, char ch){ return n * 10 + (ch-'0');}); 
} 

int main() 
{ 
    char value[8] = {'1','2','3','4','0','0','1','4'}; 
    int total1 = getTotal(value, 0, 4); 
    int total2 = getTotal(value, 4, 8); 
    std::cout << total1 << " " << total2; 
} 

std::accumulateの使用量とラムダ関数を注意してください。私たちがしたのは、それぞれの小計に10を掛け合わせたものです。文字は単に'0'を引いて数値に変換されます。私はあなたがこれをしたい理由を理解し始めることはできませんが、 `memcpy`はあなたを助けるかもしれない

Live Example

+1

'char []'に固定幅の10進数のASCIIテキストが含まれている場合、これは良いアプローチになります。私はこの問題をテキストではなくバイナリデータであると解釈しましたが、実際にはこれが正しいとは言えませんでした。 –

+0

^同じです。私はそれが 'atoi'よりもキャストのものになるはずだったと思った。 – Charles

関連する問題