🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1329閲覧

文字列で指定した一部を整数に変換したい。

grops

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/11/18 06:49

アセンブラなら直ぐに現実できそうなのですが
Cを使い慣れていないのでなかなか実現できません。
文字列の一部を整数として認識したいのですが
やり方が判りません。
ポインタ変数のアドレスを文字列の位置と
同じに指定できれば解決するはずなのですが

ソースコードのような文字列を指定して
結果が⁻1になるようなプログラムを作りたいです。

簡潔に書くには
どのように書けばいいでしょうか?

発生している問題・エラーメッセージ

error: cannot convert ‘unsigned char*’ to ‘int*’ in assignment

該当のソースコード

#include <stdio.h>
#include <sstream>
#include <string.h>
int main(void)
{
//文字列の2文字目から2バイトを16ビットの整数としたい
unsigned char data[5]= {0x14,0xFF,0xFF,0xEF,0};

int *i1 = NULL;
i1 = &data[1];
printf("%d",*i1);
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/11/18 06:54

マシン環境は何でしょうか(intは16ビット幅ですか)?
grops

2019/11/18 06:57

int は16ビット幅です。 環境は色々変わるので環境に左右されない仕様で作成したいです。
cateye

2019/11/18 07:42 編集

〉2文字目から2バイトを16ビットの整数としたい ・・・これって、0x14,0xFF,0xFF,0xEF,0→0xFFFFですか?
cateye

2019/11/18 07:44

Cに、ストリングストリーム(sstream)はありません。
cateye

2019/11/18 08:06 編集

誤記
guest

回答3

0

ベストアンサー

error: cannot convert ‘unsigned char*’ to ‘int*’ in assignment

了解。キャストすればよいと思います。たぶんこれで当面の対策になると思います。

C

1 int *i1; // NULLで初期化する必要無し 2 i1 = (int*) &data[1]; // キャストする 3 printf("%d",*i1);

<stdint.h> がインクルードできる環境なら int16_t 型が使えるはずで、int16_t が良いけど、それが使えない環境なら short 型を使うのが良いかもしれない。かなり多くのコンパイラが16bit整数はshort型でアクセスできます。
それを踏まえて上記を簡潔に書き直すなら、こうです。もはやポインタ変数は不要です。

C

1 printf("%d", *(short*) &data[1]);

data[1] のアドレスを short 型のアドレスとみなす、そしてそこの値を読みだす、というような意味になります。

投稿2019/11/18 07:46

編集2019/11/18 07:58
rubato6809

総合スコア1382

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grops

2019/11/18 08:42

皆さん回答ありがとうございます。 キャストを使えばいい なるほど 勉強になりました。 これで解決できると思います。
guest

0

int k = data[1]|(data[2]<<8);

これでどうでしょう


intのサイズが変わると結果が変わるようなコード
エンディアンが変わると結果が変わるようなコード
は書かないようにしましょうねっ

投稿2019/11/18 07:03

編集2019/11/18 07:13
y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rubato6809

2019/11/18 08:10

> エンディアンが変わると結果が変わるようなコードは書かないようにしましょう でも、その計算のやり方だとビッグエンディアンでは値が違ってしまう気がする。 しかも int が 32bit だと 0xff, 0xff は 65535 になって、-1にならないような気もする。
y_waiwai

2019/11/18 08:14

同じデータ列を与えられていれば、ビッグだろうがリトルだろうが結果は一緒です 16ビットint での -1 ってのはunsignedにすると0xffffですよ
rubato6809

2019/11/18 08:18

もしそれが 0xFE, 0xFF だったら? -2 それとも...
y_waiwai

2019/11/18 08:26

int* i1 = (void*)&data[1]; printf("%d",*i1); がどういう結果になるのか、 ビッグエンディアン、リトルエンディアン、32ビット、16ビット、の各組み合わせでどういう結果になるのか考えてみたらどうでしょうか。
rubato6809

2019/11/18 08:29

そう、それは「環境に左右されない」を求めている質問者にこそ考えてもらいたい所ですね。
guest

0

どれが正解?

text

1usr ~/Project/test % ./a.out 2ffff 3efff 4ffef

c

1#include <stdio.h> 2 3int main(void) 4{ 5 unsigned char data[5]= {0x14,0xFF,0xFF,0xEF,0}; 6 7 printf("%04hx\n",*(unsigned short *)(&data[1])); 8 printf("%04hx\n",*(unsigned short *)(&data[2])); 9 // 10 unsigned short s= (unsigned short)(data[2] << 8 | data[3]); 11 printf("%04hx\n",s); 12 13 return 0; 14}

投稿2019/11/18 08:02

編集2019/11/18 08:23
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/11/18 08:09 編集

Cに文字列はありません。 バイトの配列です。・・・たまたまそれが、文字コードで最後に終端記号(\0)が付いているだけです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問