2017-12-10 7 views
1

したがって、生のバイト形式の変数intを含むファイル記述子から読み込みました。バッファ内に格納されたバイトを変数に変換する方法は?

だから私はやってる:

char buffer[sizeof(int)]; 
ssize_t sizeOfFile = read(sock_fd, buffer, sizeof(int)); 

int extractedInt = ???; 

私は整数にそのバッファを変換できますか?私はmemcpyを考えていたが、より良い方法があるかどうか疑問に思っていた。

+1

あなたはint型に直接読むことができたが。 – tkausl

+0

また、 'char buffer [sizeof(int)]'と 'int value'メンバで' union'を定義してください。ファイルを 'buffer'にロードし、次にint値' value'を使います。 – i486

+0

https://linux.die.net/man/3/htons - ネットワーク上で通信するために、このファンクションファミリを使用してください。 –

答えて

2

あなたは整数

int extractedInt; 
ssize_t sizeOfFile = read(sock_fd, &extractedInt, sizeof(int)); 

readは、int型のバイトのサイズを読んで、そしてextractedIntにそれらを格納する直接読み取ることができます。

intが、実際にはintに変換するファイル内の文字列である場合、手順は少し異なります。

#define SIZE 20 

char buffer[SIZE]; // ensure there is enough space for a string containing an integer 
ssize_t sizeOfFile = read(sock_fd, buffer, SIZE); 

int extractedInt = atoi(buffer); // convert string to integer 
+3

注意する必要があるのは、着信バイトオーダーがローカルマシンのバイトオーダーに一致することです。 (ビッグエンディアンはネットワークプロトコルでよく使われます。)また、次の4バイトに 'int'が含まれていることが分かっていればうまくいきます。それはOPが求めていたものですが、時には、パケットやその他のメッセージ全体を読んで解析する前に、必要なintがどこにあるのかを調べることがあります。この場合、 'memcpy'の解法が便利です。完全な答えにはそれを含めることができます。 –

0

私はあなたのコードからあなたがネットワークから読んでいると推測できます。これは、バッファからintを読み取るだけでは移植できません。ネットワークプロトコルでエンディアンを選択しましたが、プログラムが実行されるすべてのプラットフォームが同じであると予想できないため、変換が正しく行われません。 readintを返すように提案する他の提案された解決策でも、同じ問題が発生します。

あなたのケースでは、配列を繰り返し処理し、プラットフォームのエンディアンに応じてバイトを正しい場所に配置することによって整数を計算するというアドバイスしかできません。

GCCのマクロ__BYTE_ORDER__を使用すると、ビルドターゲットプラットフォームのエンディアンを検出できます。

ビッグエンディアンであるネットワークデータの例があります:

// construct an `int` with the bytes in the given buffer 
// considering the buffer contains the representation 
// of an int in big endian 
int buffer_to_int(char* buffer, int buffer_size) { 
    int result = 0; 
    int i; 
    char sign = buffer[0] & 0x80; 
    char * res_bytes = (char*)&result; // this pointer allows to access the int bytes 
    int offset = sizeof(int) - buffer_size; 

    if(sign != 0) 
     sign = 0xFF; 

    if(offset < 0) { 
     // not representable with a `int` type 
     // we chose here to return the closest representable value 
     if(sign == 0) { //positive 
      return INT_MAX; 
     } else { 
      return INT_MIN; 
     } 
    } 

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 
    for(i=0; i<buffer_size; i++) { 
     res_bytes[i] = buffer[buffer_size-i-1]; // invert the bytes 
    } 

    for(i=0; i<offset; i++){ 
     res_bytes[buffer_size+i] = sign; 
    } 
#else 
    // same endianness, so simply copy bytes using memcpy 
    memcpy(&result + offset, buffer, buffer_size); 

    for(i=0; i<offset; i++){ 
     res_bytes[i] = sign; 
    } 
#endif 

    return result; 
} 
関連する問題