これ何て呼びますか

#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文字だけ数値として扱えるのでしょうか?

質問者からの補足コメント

  • すいません。補足で、sscanfとsscanf_sの違いをわかりやすく例題を用いて説明して頂けないでしょうか?

      補足日時:2021/02/21 16:10

A 回答 (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の制定委員会はマイクロソフトの影響力を最小にしよう、って動く事は充分考えられる。っつーか、ずーっとそうだったんじゃないかな、とは思う。軋轢があるのだ。
実はプログラミング言語の公式標準化、と言うのは必ずしも工学的な判断、と言うより多分に政治的な影響を受けると思う。
    • good
    • 0

質問者さんが上達を希望するならリファレンスを読めるようにならないことにはどうにもなりませんよ

    • good
    • 1
この回答へのお礼

ありがとうこざいます。

お礼日時:2021/02/21 17:48

実行するのはこの部分だけですよ



#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);
}
    • good
    • 0

%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');
    • good
    • 0
この回答へのお礼

すいません。プログラムを実行したら、sscanfに緑の下線部が出てエラーが出ます。

お礼日時:2021/02/21 16:32

あ、それと。



> アドレスからヌルになるまでを収納する

収納しない。
もう512回も言ったけど、「C言語には文字列なんざありません」。
従って、収納なんざ出来ません。
    • good
    • 3

| プログラムの%1dってなんですか?



%d で、10進数として扱うって意味です。
%1d で、10進数を一桁扱うって意味です。
(例えば%20dなら、20桁になります)

| ヌルになるまでを収納すると聞きました。

%dならそう考えて大丈夫です。
今回は、数値が間に追加されているので桁指定ありってことです。
    • good
    • 1

> %1dってなんですか?



フォーマット指定子一覧:
https://www.k-cube.co.jp/wakaba/server/format.html

質問全部がフォーマット指定子の役割。

・・・ってか仕様書読んだ?
仕様書が難しいのなら最低でも関数の動作確認は自分でネットで調べる、くらいしないとどーしようもないでしょう。
    • good
    • 2

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!