web-dev-qa-db-ja.com

Cのintをchar配列にキャスト

キャストを使用するだけでCでintを「文字列」に変換することは可能ですか? atoi()sprintf()などの関数がない場合

私が欲しいのはこのようなものです:

_int main(int argc, char *argv[]) {
    int i = 500;
    char c[4];

    c = (char)i;
    i = 0;
    i = (int)c;
}
_

その理由は、2つのランダムな整数(0〜500)を生成し、両方をメッセージキュー内の1つの文字列として別のプロセスに送信する必要があるためです。他のプロセスはメッセージを受信し、LCMを実行します。

atoi()itoa()の使い方を知っています。しかし、私の先生はただキャストを使いたいと思っています。

また、次のものがコンパイルできないのはなぜですか?

_typedef struct
{
    int x;
    int y;
} int_t;

typedef struct
{
    char x[sizeof(int)];
    char y[sizeof(int)];
} char_t;

int main(int argc, char *argv[])
{
    int_t Rand_int;
    char_t Rand_char;

    Rand_int.x = (Rand() % 501);
    Rand_int.y = (Rand() % 501);

    Rand_char = (char_t)Rand_int;
}
_
9
Bodosko

もちろん、それは不可能です。なぜなら、配列はオブジェクトであり、storageが必要だからです。キャストの結果はvaluesであり、objectsではありません。 Cのポイント/パワーの全体は、オブジェクトのストレージと寿命を制御できると言う人もいます。

整数の10進数表現を含む文字列を生成する適切な方法は、自分でストレージを作成し、snprintfを使用することです。

char buf[sizeof(int)*3+2];
snprintf(buf, sizeof buf, "%d", n);
11
R..

500"500"に変換する必要があります。

"500"は、'5''0''0'0と同じです。最後の要素0は、文字列のnullターミネータです。

5005 * 100 + 0 * 10 + 0 * 1と同じです。ここでいくつかの計算を行う必要があります。基本的には、/演算子を使用する必要があります。

次に、これも役立ちます:'5''0' + 5と同じです。

4
ouah

エンディアンのため、キャストはこれを行うための恐ろしい方法ですが、とにかく例を挙げます-有用な場合があります(これらのタイプのキャストのコンパイラー処理により、最近では共用体の方がうまく機能します)。

#include <stdio.h> //for printf 
#define INT(x) ((int*)(x)) //these are not endian-safe methods
#define CHAR(x) ((char*)(x))
int main(void)
{
    int *x=INT(&"HI !");
    printf("%X\n",*x); //look up the ascii and note the order
    printf("%s\n",CHAR(x));
    return 0;
}

値が500未満のintの場合、最上位バイトが最初に来ると、 "ストリング" (char配列へのポインタ) ""(または{0})ですが、エンディアンがLSBファースト(x86はリトルエンディアン)の場合、使用可能な3バイトが得られます。 "ストリング" char *(必ずしも人間が読める文字とは限りません)ですが、整数にゼロバイトがあることは保証されません。通常の文字列関数を実行した場合、intが格納されているアドレスへのポインタしかありません。それは、元のintの終わりを越えて無人ランドに行きます(小さなテストプログラムでは、多くの場合、環境変数になります)...とにかく移植性を高めるには、ネットワークバイトオーダーを使用できます(リトルエンディアンの場合、 no-op):

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

これらの関数は、ネットワークバイトオーダーを取得するために必要に応じてバイトスワップします。 x86では、それらは最適化されますので、移植性のために使用することもできます。

2
technosaurus

正確なコード化された回答を提供せずに、整数の各桁をループして(%演算子を使用して剰余10を計算することにより)、その値をASCII値「0」、結果をcharにキャストバックし、その結果をnullで終了する文字列に配置します。

暗黙のキャストが存在しないように見せかける例は次のようになります。

char c = (char) ( ((int) '0') + 5 ); // c should now be '5'.

結果の文字列の長さは、数値の対数10を計算するか、realloc()を使用して動的に割り当てるだけで決定できます。

2
CmdrMoozy

まだリストされていないからです:snprintfを使用して可変サイズの割り当てでintをchar配列に変換する方法:

int value = 5

// this will just output the length which is to expect
int length = snprintf( NULL, 0, "%d", value );

char* valueAsString = malloc( length + 1 );// one more for 0-terminator
snprintf( valueAsString, length + 1, "%d", value );
1
Alex

分割数を取得し、バッファに1つずつ追加します

char *int2str(int nb) {
    int i = 0;
    int div = 1;
    int cmp = nb;
    char *nbr = malloc(sizeof(char) * 12);

    if (!nbr)
        return (NULL);
    if (nb < 0)
        nbr[i++] = '-';
    while ((cmp /= 10) != 0)
        div = div * 10;
    while (div > 0) {
        nbr[i++] = abs(nb / div) + 48;
        nb = nb % div;
        div /= 10;
    }
    nbr[i] = '\0';
    return (nbr);
}
0
Locoder