質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.37%
C

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

Q&A

解決済

3回答

2070閲覧

キーボードからの入力を1文字ずつ取得したい

h_proc

総合スコア68

C

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

0グッド

0クリップ

投稿2020/08/20 14:24

キーボードから1,0で表したデータを入力してもらい(例えば11001など)、入力されたデータを16進数に変えて、ビット演算を行いたいです。
scanf_s関数でキーボードからの入力を受けています。
16進数に直す方法が分からなかったため、ひとまず、
端から一文字ずつ2のn乗を掛け算して、10進数に直して、そこから16進数に直すことを考えました。
そこで、generate[i]で1文字ずつ取得しようとしたのですが、表示させてみたところ、
49
49
48
48
10
と表示されてしまいました。(例の場合だと、11001と表示されると期待していました。)
➀これは何が起きているのでしょうか?
➁キーボードからの入力を1文字ずつ取得することはできないのでしょうか?
➂16進数に直す方法は他にもありますか?
質問したいことは以上3点です。よろしくお願い致します。

該当するコードです。

c

1printf("入力してください\n"); 2 char generate[32]; 3 fgets(generate,sizeof(generate),stdin); 4 int i; 5 6 for (i = 0; generate[i] != '\0'; i++) { 7 printf("%d\n", (generate[i])); 8 }

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

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

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

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

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

cateye

2020/08/20 14:33 編集

49 は、数字の '1'ということは分かっていますか?
1T2R3M4

2020/08/20 14:37

ASCIIコードの知見はありますか。
h_proc

2020/08/20 14:38

すみません、分かっていません。
thkana

2020/08/20 23:45

> scanf_s関数でキーボードからの入力を受けています。 え? それだけであれば本質的な問題ではないですけれど、そういうミスをしていると他の部分についても信頼できるかどうか、質問に載せているソースは検討に値するものなのか?という疑念を持たざるをえなくなります。
guest

回答3

0

コンピュータは、基本的に「数値」しか扱えません。でも、文字も扱いたい、どうしましょう。
一つ一つの文字に数値を割り当てて、文字として扱いたいときにはその約束のもとに「割当表」に基づいて数値と文字を置き換えて扱うことにしました。
半角文字について事実上ほとんどのCの処理系が採用しているASCIIコードという割当表によれば、文字'0'は数値48, '1'は数値49,...'9'は数値57, 'A'は数値65,として扱われます。
(その意味で、ソフトウェアの中身の話をするときは「数値」と「数字」を厳密に区別して考えるべきです。数値というのは値そのもの、数字は数値を表す単独の文字あるいは文字の並びです。)

fgetsでは(あるいは、scanf/scanf_sの"%s"書式指定では)、文字列を取り込みます。つまり、文字'0'が与えられたらそれは数値48を意味します。
また、改行文字は(あなたのシステムでは)数値10だったのでしょう。fgetsでは指定文字数以内なら改行までを取り込みますから、それが結果にあらわれています。
以上「➀これは何が起きているのでしょうか?」

そして、48とか49がそれぞれ1文字です。1文字ずつ取得できています。これが「➁キーボードからの入力を1文字ずつ取得することはできないのでしょうか?」の回答になりますでしょうか。

➂16進数に直す方法は他にもありますか?

「他」というのは一つできてから考えることと思いますが。
「16進数に直す」ですか?
先程の「数値」の話ですが、例えば0b11001==0x19は真ですし、0x19==25も真です。数値は、その表記によらず同じ「値」を意味します。百と言おうとone handredと言おうと数は変わらないのと同様。では、「16進数に直す」とは何を意味するのでしょう?
例えば「16進数表記で表示したい」のだとすると、
数値として取り込んであれば、printf("%x",数値);で16進数として表示されます。これが一番簡単かと思いますし、これ以外の何かをする理由もないでしょう(お勉強として、以外は)。

あるいは、数値を経由せずに、文字列を下から4桁ずつ区切って、"0000"だったら'0'、'0001'だったら'1',...'1111'だったら'f'と置き換える、なんていう方法も考えられます。たった16種しかパターンがないので。

そもそものお題も読み返すと結構悩ましいですね。

キーボードから1,0で表したデータを入力してもらい(例えば11001など)、入力されたデータを16進数に変えて、ビット演算を行いたいです。

まず「1,0で表したデータ(例えば11001など)」これは、2進数表記であることを意図している、と思っていいですか?

「16進数に変えて」は上述の「16進数に直す」と同じ話ですが、しかし「入力されたデータを0x11001と解釈したかったのでは、という疑念がわずかに出たりもします。

そしてさらにビット演算を行いたい? ビット演算は、コンピュータの内部で数値が2進数で保存されていることが前提で行われるものです。16進数とか関係ありません。どういう結果が得られれば満足なのでしょう?

投稿2020/08/21 00:24

thkana

総合スコア7703

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

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

0

ベストアンサー

2進数 16進数 とは
「図解」 2進数=10進数=16進数 変換する為の計算方法!
2進数16進数変換は検索すれば洗練されたコードが沢山あるのでご参考までに。

これでどうでしょう。

C

1#include <stdio.h> 2 3int main() { 4 printf("入力してください\n"); 5 char generate[32]; 6 fgets(generate, sizeof(generate), stdin); 7 int i; 8 9 for (i = 0; generate[i] != '\n'; i++) { 10 int x = generate[i] - '0'; 11 printf("%d\n", x); 12 } 13 14 getchar(); 15 return 0; 16}

投稿2020/08/20 14:41

編集2020/08/20 14:56
mjk

総合スコア303

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

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

h_proc

2020/08/20 23:44

ありがとうございます。
guest

0

49,49,48,48,10 は、文字列"1100"+改行('\n')です。
printf("%d\n", (generate[i]));→printf("%d\n", (generate[i]-'0'));
とやってみましょう。また、fgets()は、改行まで読み込みます。
数値に10進も16進もありません、1は1,5は5です。
見た目を変えたいだけなら、printf()の書式を"%x"にして下さい。
「追記」変換方法の参考にして下さい。

c

1#include <stdio.h> 2// 3static int cnv(const char *ascp) 4{ 5 int ans = 0; 6 for(; *ascp; ascp++) { 7 ans <<= 1; 8 ans |= *ascp - '0'; 9 } 10 return ans; 11} 12// 13int main(void) 14{ 15 // 16 char ascii[] = "11001"; 17 int ans = cnv(ascii); 18 printf("%d\n", ans); 19 20 return 0; 21}

結果↓
usr ~/Project/test % ./a.out
25

11001

投稿2020/08/20 14:39

編集2020/08/20 15:15
cateye

総合スコア6851

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

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

cateye

2020/08/20 15:20 編集

11001は、25です。書式を"%d\n"から"%x\n"に変えれば19が出力されます。 fgets()に対応するには、for(; *ascp; ascp++) をfor(; *ascp!='\n'; ascp++)にしてください。
h_proc

2020/08/20 23:43 編集

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問