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

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

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

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

Q&A

解決済

5回答

4136閲覧

二桁の数字を文字列に変換したい

vaitarika

総合スコア29

C

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

0グッド

0クリップ

投稿2019/04/17 03:49

int型として入力された二桁の数字を文字列に変換したいです。
具体的には、例えば「18」という数字を「"18"」という文字列に変換させたいと考えています。

どのような操作を行えば二桁の数字を文字列に変換することができるでしょうか。

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

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

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

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

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

guest

回答5

0

んでは別回答を

int value=13;
char bf[3];
bf[0]=((value/10)%10)+'0';
bf[1]=(value%10)+'0';
bf[2]='\0';

投稿2019/04/17 07:20

y_waiwai

総合スコア87782

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

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

0

ベストアンサー

c

1#include <stdio.h> 2 3int value = 18; 4char output[3]; /* 2桁+終端 = 3文字 */ 5snprintf(output, 3, "%d", value);

投稿2019/04/17 03:53

編集2019/04/17 06:53
yohhoy

総合スコア6191

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

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

0

基本的には他の回答者の方々が答えたような操作をします。補足を加えて説明します。


まず、「二桁の数」と言ったら文字列です。int型は単なる数値なので桁数はないです。

問題を考えるときに、「入力された数値は必ず二桁で表せるような値になっている」ということを暗黙に仮定してしまっていませんか。int型はもっと広い範囲の値を表せます。数値を入力するためのコードで、値の範囲を検査して妥当なものだけ受け付けているとは限りませんよね。入力された値が妥当かどうかを検査しましょう。

そこで、ご質問の要件を「入力されたint型の数値が二桁の数字で表せるときは文字列に変換する」と解釈することにしました。こんなコードでしょう。

c

1#include <stdio.h> 2 3int val = 99; 4char buf[3]; 5 6... 7 8 if (10 <= val && val <= 99) 9 snprintf(buf, sizeof buf, "%d", val); 10 else 11 エラー処理; 12 13...

「エラー処理」のところは自分で考えて下さい。

配列bufのサイズは、ほかの回答者さんたちも書いていらっしゃる通り、「数字の桁数」プラス「文字列終端の '\0'」の分だけ必要です。Pythonなどの「高級」な言語とちがって、Cではデータの中身がメモリ上でどう表現されているかをいちいち気にして、必要な大きさのメモリ領域を明示的に確保しなければなりません (Pythonでの文字列はメモリ上でもっと複雑な仕組みで表現されていますが、プログラミングの際はそんなことを気にしなくていいし、必要なメモリ領域も自動的に確保してくれます)。

数値を文字列に変換して配列に書き込む方法ですが、すでにC標準ライブラリにそういう関数がありますから、再発明することもないでしょう。それを使いました。

しかし、配列の大きさは今回の目的に必要な最小限の3バイトしか確保してありませんから、結果の文字列の長さは絶対に2バイトを超えないようにしなければなりません (1バイト少なくなるのは、文字列終端の '\0' で1バイト使うため)。

  • sprintfなどを使った場合、万一確保した長さを超えてもお構いなく配列のために確保したメモリの外にまで書き込んでしまいます (「バッファオーバーラン」といって、システムの脆弱性につながる危険な動作です)。
  • snprintfを使うと、指定した長さ以上は書き込まないことが保証されます。今回はそういうことは起きないかもしれませんが、今後プログラムを修正していくとそういうコードになってしまうかもしれません。こちらを使います。

それぞれの関数の詳しい説明は自分で調べて下さい。


回答は以上……なのですが、ひとつ気づいたことがあります。入力される数値はint型、つまり符号つき整数ですよね。

そこでちょっとまわりの人に聞いてみたところ、「-10」なんかも「二桁の数字」だと言っています……。負の数も受け付けるようにしたほうがよさそうです。

また、±9 以内の数も、二桁で入力できると言えば言えるので、受け付けてしまっていいように思います。ということでコードを修正しました。

c

1#include <stdio.h> 2 3int val = -99; 4char buf[4]; 5 6... 7 8 if (-99 <= val && val <= 99) 9 snprintf(buf, sizeof buf, "%d", val); 10 else 11 エラー処理; 12 13...

ifの条件が変わっただけではないです。bufのサイズが変わりました。今度は結果に「-」がつくことがあるので、さらに1バイト必要です。もしもサイズが元のままだと、先に書いた通り、snprintf関数は結果のはみ出る部分を切り捨てます。つまり「-10」であるべきものが「-1」になってしまいます。

snprintfの呼び出しそのものは変わっていません。他の回答者には、変換の処理を自力で書いたかたもいらっしゃいます。Cでどのような処理をしているのかを理解するには非常によいのですが、今回のように要件が変更になったときには期待通りの結果を出せなくなるので、書き直しが必要になります。C標準ライブラリのsnprintf関数はもともと負の数の変換にも対応していますから、そのまま使えます。

以上ですが、このような回答でよいでしょうか? (誰に聞いているのか)

投稿2019/04/22 13:23

ikedas

総合スコア4343

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

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

0

c

1#include <stdio.h> 2 3int main() { 4 int a = 18; 5 6 char s[3] = {'0', '0', '\0'}; 7 8 printf("%s\n", s); 9 10 s[0] += a / 10; 11 s[1] += a % 10; 12 printf("%s\n", s); 13 return 0; 14}

投稿2019/04/17 13:55

katoy

総合スコア22324

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

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

0

c

1#include <stdio.h> 2#include <stdlib.h> 3 4int digits(int n); 5 6int main(void){ 7 8 int n = 18; 9 int i; 10 char output[3]; 11 int m = digits(n); 12 for(i = 0; i < m; i++){ 13 output[m - i - 1] = '0' + n % 10; 14 n /= 10; 15 } 16 output[2] = '\0'; 17 printf("%s",output); 18 return 0; 19} 20int digits(int n) 21{ 22 int digit = 0; 23 while(n > 0){ 24 n /= 10; 25 digit++; 26 } 27 return digit; 28}

投稿2019/04/17 08:46

編集2019/06/03 03:28
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

raccy

2019/05/03 03:23

なぜ、こんなに低評価なのかわからない人のために解説しておきます。 valueが18の場合、textが{'8', '1', '\0', ...}になる。つまり、"18"ではなく"81"になる。 以上です。
Zuishin

2019/05/03 03:59

あと、0 の時に空文字になったり、int の最大値の時にバッファの大きさが足りなかったりします。 それに加えてすでにある回答を超えるものではなく、まったく無駄な処理をしています。 関数の命名が悪く、main が大きく、何度も同じループを使って効率が悪く、反面教師として使うべきソースになっています。 ですので、これを書き換えるのであれば、数字が反転するところだけでなく他の悪いところもすべて直してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問