![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
#include <stdio.h>int main(void) {
char str[] = "0123456789";
int a, b;
sscanf(str + 2, "%1d", &a);//3番目の数字があるアドレスを指定して、1文字だけ数値として読み取る
sscanf(str + 5, "%1d", &b);//6番目の数字があるアドレスを指定して、1文字だけ数値として読み取る
printf("%d\n", a + b);
}
のプログラムの%1dってなんですか?
また、sscanf(str + 2, "%1d", &a)は3番目の数字があるアドレスを指定して、1文字だけ数値として読み取るのような働きをするのですか?
sscanfは文字としての2を数字としての2に変える働きもあるのでしょうか?
どこで文字としての2が数字としての2になったのか、どうか詳しく教えて下さい。
本で読んだときはあるアドレスからヌルになるまでを収納すると聞きました。なぜ限定的に1文字だけ数値として扱えるのでしょうか?
No.7ベストアンサー
- 回答日時:
> sscanfとsscanf_sの違い
誤解を畏れずに言うと「無い」。
sscanfとsscanf_sの違いは機能の問題ではなく、「セキュリティチェック」をするかどうか、が違い。
_sはsecureの略、だと言われている。
もし現実的に、つまり実装上の違いがあるとしたら、
マイクロソフトのコンパイラ -> sscanf_sが推奨される。
gcc/clang等のフリーソフトウェア系のコンパイラ -> sscanf_sは使えない
と言うのが違い。
これが実はちょっとややこしい。
日本の、JISのC言語規格(JISX3010:2003)にはsscanf_sなんて関数は無い。
つまり、日本国内に於いては標準関数ではない、と言う事。
従って、「C言語の機能」ではなく、ある特定の(つまりマイクロソフトの)コンパイラでの「追加」機能の話になる。
従って、知りたいのならマイクロソフトへどうぞ、ってのが一つの答え。
一方、JISのC言語規格は、実は1999年に制定されたISO(国際標準化機構)の通称C99と言う規格に基づいている。そしてC99は最新規格ではない。要するに日本の国内規格は世界標準に追いついてない、って事だ。
そして、最新規格はC11(改訂版はC17だがこれはC11のマイナーアップデート/バグ修正版)なんだけど、ここの追加項目Kにsscanf_sが含まれている。
追加項目Kとは「境界線チェックを行う」(多分)37個くらいのセキュリティチェック版の関数がある。そして「追加項目」と言うのは実装者が実装しようがしまいが、関係ない、どっちでもいい、要するにオプショナル項目である。
背景を言うと、元々マイクロソフトはC++の仕様に追いつくのが目的だったんだけど、Cは全然放ったらかしだった。もちろん主要製品はC++の方だったから、だ。
ただ、Cの古来からの入出力関数が「安全ではない」と言うので、独自に自社のCコンパイラ用にセキュリティチェック版の入出力用関数を色々と追加していた。
それをC11の制定委員会に提案したわけだ。「こっちの方が安全だろ? 」って事で。標準化すべきだ、と。
C11の制定委員会は受諾したけど、言語仕様の本体に含める事は慎重に避けたわけ。それで言わば、「仕様書のオマケ」としてマイクロソフトから提案された「セキュリティチェック版」関数を含める事とした。「実装しても実装せんでもどっちでも良いよ」と。
そこで晴れてC11にマイクロソフトが提案した「安全版」関数群が載る事になったわけだけど、GCCとかClangの実装者は「オマケだから」ってんで実装してないんだな。
というわけで、「標準化」されてる筈なのに、マイクロソフトのコンパイラでは使えても他の実装では必ずしも使えない、と言うヘンな結果になっている。
分かりましたか?
※: ぶっちゃけ、Cの制定委員会とマイクロソフトの間には政治的なアレコレもあると思う。ベンダーとして考えるとマイクロソフトは確かに最強で最大のユーザー数を抱えてるのは事実なんで、マイクロソフトの発言と言うのは大変大きいわけだ。
と言う事は「マイクロソフトの言う事」をそのまま受け入れているとヤバい、ってのがAppleなりFSFなりの判断であって、かつ、Cの制定委員会はマイクロソフトの影響力を最小にしよう、って動く事は充分考えられる。っつーか、ずーっとそうだったんじゃないかな、とは思う。軋轢があるのだ。
実はプログラミング言語の公式標準化、と言うのは必ずしも工学的な判断、と言うより多分に政治的な影響を受けると思う。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?e8efa67)
No.5
- 回答日時:
実行するのはこの部分だけですよ
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[] = "012 345 数値";
int a, b;
char s[10]={'\0'};
sscanf(str, "%d %d %s", &a, &b, s);
printf("%d %d %s\n", a, b, s);
}
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?e8efa67)
No.4
- 回答日時:
%1dは1桁表示
sscanfの使い方の勉強中ならsscanfの用途が間違ってる気がします
通常は以下のように文字列の中にある数値や文字列などを別けたい時に使う物
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[] = "012 345 数値";
int a, b;
char s[10]={'\0'};
sscanf(str, "%d %d %s", &a, &b, s);
printf("%d %d %s\n", a, b, s);
}
以下の中から一文字だけ数値として出力したいなら素直に以下のようにしましょう
char str[] = "0123456789";
printf("%d\n", str[4]-'0');
No.3
- 回答日時:
あ、それと。
> アドレスからヌルになるまでを収納する
収納しない。
もう512回も言ったけど、「C言語には文字列なんざありません」。
従って、収納なんざ出来ません。
No.2
- 回答日時:
| プログラムの%1dってなんですか?
%d で、10進数として扱うって意味です。
%1d で、10進数を一桁扱うって意味です。
(例えば%20dなら、20桁になります)
| ヌルになるまでを収納すると聞きました。
%dならそう考えて大丈夫です。
今回は、数値が間に追加されているので桁指定ありってことです。
No.1
- 回答日時:
> %1dってなんですか?
フォーマット指定子一覧:
https://www.k-cube.co.jp/wakaba/server/format.html
質問全部がフォーマット指定子の役割。
・・・ってか仕様書読んだ?
仕様書が難しいのなら最低でも関数の動作確認は自分でネットで調べる、くらいしないとどーしようもないでしょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Visual Basic(VBA) VBA ユーザーフォームからSubプロージャ―に値を引き渡す方法 3 2023/04/09 01:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
charでの計算?
-
charからLPTSTRへの変換方法
-
文字列から空白を取り除きたい...
-
double型の値をchar配列に変換...
-
c言語でユーザ関数を利用して入...
-
テキストデータをそのままバイ...
-
C言語について。
-
CStringをwchar_tに変換したい
-
enumの記述について。
-
アルファベットの並べ替え
-
'const char *' 型は 'char *' ...
-
3桁区切(コンマ)記号をつけ...
-
C言語のポインターで詰まっている
-
switch文で文字を比較すること...
-
pingの結果を取得する方法
-
配列をnビットシフトする
-
for文 アスタリスクで形を作る
-
ncursesで...
-
C言語の入力した文字を反転させ...
-
Visual Studio strcpyについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
テキストデータをそのままバイ...
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
2曲同時再生するにはどうした...
-
C言語の入力した文字を反転させ...
-
配列をnビットシフトする
-
3桁区切(コンマ)記号をつけ...
-
int main()の・・・
-
型変換
-
CStringをwchar_tに変換したい
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
double型の値をchar配列に変換...
-
絶対パスからのファイル名の切...
-
switch文で文字を比較すること...
-
c++ 文字列を入力して、一文字...
おすすめ情報
すいません。補足で、sscanfとsscanf_sの違いをわかりやすく例題を用いて説明して頂けないでしょうか?