1

多くの行と列のマトリックスを含むファイルがあります。以下のようになります。

fa ff 00 10 00
ee ee 00 00 30
dd d1 00 aa 00

行列の各エントリは、8 ビット値の 16 進数です。このファイルを 2 次元配列に読み込みたいと思います。

2 つの問題があります。

  1. 私のコードで read メソッドを使用すると、*マトリックスの各エントリ (2 文字) を持つ配列が含まれます。各エントリを 2 文字ではなく 1 つの変数に渡すにはどうすればよいですか?

  2. 単一の変数に渡すとき、文字から16進数に変換する方法は? つまり、「ff」は 0xff に変換する必要があります。

私のコードの一部は以下のとおりです。より良い方法を使用できる場合は、トークン化機能を回避できます。

char** tokens;
char** it;

while (fgets(line, sizeof(line), file) != NULL){ /* read a line */
    tokens = tokenize(line);    // split line

    for(it=tokens; it && *it; ++it){
        printf("%s\n", *it);
        free(*it);
    } // end for
} // end while

char** tokenize(const char* str){
    int count = 0;
    int capacity = 10;
    char** result = malloc(capacity*sizeof(*result));

    const char* e=str;

    if (e) do {
        const char* s=e;
        e=strpbrk(s," ");

        if (count >= capacity)
            result = realloc(result, (capacity*=2)*sizeof(*result));

        result[count++] = e? strndup(s, e-s) : strdup(s);
    } while (e && *(++e));

    if (count >= capacity)
        result = realloc(result, (capacity+=1)*sizeof(*result));
    result[count++] = 0;

    return result;
}
4

4 に答える 4

7

ここに答えの半分があります: 16 進文字列を読み取って値に変換するには、次のようにします。

#include <stdio.h>

int main(void) {
  char *myString="8e";
  int myVal;
  sscanf(myString, "%x", &myVal);
  printf("The value was read in: it is %0x in hex, or %d in decimal\n", myVal, myVal);
}

これで、質問の「2 つの文字を 1 つの変数に読み込む方法」の部分に対する答えが得られると思います。

後半については、次のことを行った場合:

while (fgets(line, sizeof(line), file) != NULL){ /* read a line */
    tokens = tokenize(line);    // split line

    for(int ii=0; tokens[ii]; i++) {
        printf("ii=%d; token = %s\n", ii, tokens[ii]);
    } // end for
} // end while

tokens配列には、求めているもの、つまり文字列が既に含まれていることがわかります。を使用してそれぞれを変換するとsscanf、たとえば次のようになります。

int myValues[10];
for(int ii=0; ii<10; ii++) {
  sscanf(tokens+ii, "%x", myValues+ii);
  printf("The %dth converted value is %d - or %x in hex\n", ii, myValues[ii], myValues[ii]);
}

これにより、必要なすべてが実行されることがわかります。上記では固定サイズの配列を使用しました -malloc動的に割り当てられた適切なサイズの配列を作成する方法を明確に知っています (の固定値ではなく10)。

もう 1 つ注意してください。配列要素のアドレスは、または単に としてmyArray[0]記述できます。その他の要素については、 と同じです。C のポインター演算の驚異の 1 つです。これがお役に立てば幸いです。&myArray[0]myArray&myArray[5]myArray+5

于 2013-10-01T01:01:21.187 に答える
2

16 進数/10 進数/2 進数などは、とにかくメモリに同じ方法で格納されている値の表現にすぎないため、16 進数への変換は意味がありません。

そうは言っても、16 進数の文字列をそれが表す数値に変換する簡単な方法は次のとおりです。

  1. 16 進文字列の先頭に追加する一時バッファーを作成し"0x"ます (文字列がある場合は、バッファーに を含め"ff"ます"0xff")。
  2. そのバッファをスキャン関数に渡し(sscanfあなたのケースで機能します)、フォーマット文字列で正しいフォーマット指定子(この場合%xは16進数)を指定します。
  3. 変数 ( に指定したアドレス) から値を取得し、sscanf好きなように使用します。
于 2013-10-01T01:02:32.117 に答える
0

hexString.cから Apple の実装を確認してください

static char byteMap[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
static int byteMapLen = sizeof(byteMap);

/* utility function to convert hex character representation to their nibble (4 bit) values */
static uint8_t
nibbleFromChar(char c)
{
    if(c >= '0' && c <= '9') return c - '0';
    if(c >= 'a' && c <= 'f') return c - 'a' + 10;
    if(c >= 'A' && c <= 'F') return c - 'A' + 10;
    return 255;
}


/* Utility function to convert nibbles (4 bit values) into a hex character representation */
static char
nibbleToChar(uint8_t nibble)
{
    if(nibble < byteMapLen) return byteMap[nibble];
    return '*';
}

/* Convert a buffer of binary values into a hex string representation */
char * bytesToHexString(uint8_t *bytes, size_t buflen)
{
    char *retval;
    int i;

    retval = malloc(buflen*2 + 1);
    for(i=0; i<buflen; i++) {
        retval[i*2] = nibbleToChar(bytes[i] >> 4);
        retval[i*2+1] = nibbleToChar(bytes[i] & 0x0f);
    }
    retval[i] = '\0';
    return retval;
}
于 2015-07-12T11:12:24.497 に答える
0

を使用してデータを数字として読み込むことができますcinscanfこれらは自動的にスペースまたは改行を分割文字として使用します。次の例を見てください。

int main() {
  int val;
  while (scanf("%x", &val) != EOF)
    printf("val we get : %x\n", val);

  return 0;
}

これがテストです。

于 2013-10-01T01:46:24.583 に答える