電子書籍の厳選無料作品が豊富!

プログラミング勉強中です。
strtol(,?,)書式の真ん中の変換終了位置というのが理解できません。色々と調べてみたのですが、理解できなかったので説明できる人がいたらお願いします。

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

  • なるほど。説明ありがとうございます。
    以前このサイトで以下のようなソースコードをみました。errno関数を用いて数字以外の入力の際、エラーが起こるようにするというものでしたが、このソースコードのstrtol関数では空っぽなポインタ変数がargpとして置かれてると思うのですが、if文の条件式にがよく分からないのですが、、


    char buff[ 256 ];
    char *argp;
    int value;

    // 文字列で入力
    scanf( "%s", buff );
    value = strtol( buff, &argp, 10 ); ←10進数で変換

    // ここでチェック
    if ( (errno != ERANGE) && (*argp != '\0') ){
     printf( "変換不可能な文字が入力されています。\n" );
     exit( 1 );
    }

    No.1の回答に寄せられた補足コメントです。 補足日時:2021/01/06 12:10
  • なるほど。他の方の説明とtrajaaさんの補足で理解できました。
    strtol関数の書式の二番目の終了位置というのが0あるいはNULLの場合は数字の変換がそのまま通るのでこの条件式を通ってエラーになることはないということですね。
    例題を用いてわかりやすく説明していただき、ありがとうございます。

    No.3の回答に寄せられた補足コメントです。 補足日時:2021/01/06 13:58
  • うーん。。NULLという存在がまだ100%分かってないですね。0になることは有り得るんですよね?

    組み込むプログラミングが数字一文字入力が基本なので今回は目をつむります。。
    ですが、後学のためにもそのような場合でも対応できるようなソースコードはどのように書けばよいでしょうか?

    No.4の回答に寄せられた補足コメントです。 補足日時:2021/01/06 19:27
  • strtol関数の書式でいうと2番目に当たる終了位置のことです。

    isdightについて調べてみたのですが、例えば以下のように変数に入力されたものが十進数なのかを判別することもできるのですか?
    int s,

    scanf("%d",&s);

    if(isdight('s')){
    printf("十進数の数字です");
    }else{
    printf("十進数の数字ではない");
    }

    No.5の回答に寄せられた補足コメントです。 補足日時:2021/01/08 00:07
  • ポインタ指定の時の記号*(アスタリスク)だと思っていたのですが違うようですね。
    勉強ぶそくでした。。
    細かい説明までありがとうございました。

    No.6の回答に寄せられた補足コメントです。 補足日時:2021/01/09 15:46

A 回答 (6件)

value = strtol( buff, &argp, 10 );


と strtol を呼び出したとすると, 帰ってきたときには argp は buff の (先頭から最初の '\0' までの) どこかの要素を指すことになるので
argp == 0
となることはない (これはポインタとしての比較). ただし
*argp == 0
となることはありえる (こっちはポインタが指している値の比較). あと strtol の返り値は long なので int の変数で受けるのはあまりよくない (使っている処理系で int と long が同じだとしても).

そして isdigit ね. isdight じゃないよ. これは引数が数字であるときに真 (0 でない値), 数字ではないときに偽 (0) を返す. なので
isdigit('s')
は (文字 's' は数字ではないので) 必ず 0.
isdigit(s)
なら s に入っている値 (を文字コードとして持つ文字) によって真偽が決まる. ASCII を使っているなら s が 48以上 57以下のとき真.
この回答への補足あり
    • good
    • 0

「0になることは有り得るんですよね?」は, 「何が」「0になること」があるかどうかを考えているのでしょうか?



数字かどうかの判定なら isdigit を使うのが本手だと思う.
この回答への補足あり
    • good
    • 0

ちょっと突っ込む.



「終了位置というの」が NULL になることはありえないよ.

それに, これだと
-635402493243073xkf
が (long が 32ビットだとして) 弾けないんじゃない?
この回答への補足あり
    • good
    • 0

この場合、(*argp != '\0')  は終端(\0)ではないという意味になります


また、 (errno != ERANGE)は、エラーの理由がint型のvalueのオーバフローではない事を意味する

その両方を満たす場合なので、値への変換に失敗していると見なす

具体的には、”12a@9”のような場合
12まで変換した結果がvalueに入る
変換は成功しているので(errno != ERANGE)が成立する

一方で"12"の次は"a"であり\0(終端)ではない
なので(*argp != '\0') も成立する

だから入力された文字列の中に数字以外の文字があると推測できる
この回答への補足あり
    • good
    • 0

変換終了位置というのは


n = strtol("77ABC", &e, 10);
という式があれば
e="ABC" を示すことになります。
n = strtol("77", &e, 10);
ならば e=NULL となります。
つまり
文字列をロング整数に変換して失敗した位置ということになります
    • good
    • 0
この回答へのお礼

なるほど。大変わかりやすく説明していただき、ありがとうございます。
つまるところ、77abcでは十進数でabcは表せず、出力すれば77になり変換失敗部分が書式の二つ目に格納される。77の場合では変換失敗はなしということでNULL(何も示さない)となるということですね。
本当にありがとうございました!

お礼日時:2021/01/06 13:53

関数のパラーメータなので、指定しない事は出来ませんが・・・・



実務上このパラメータを使う事は先ず無いですね

第一パラメータで文字列のアドレスを渡すでしょ?
そこから変換対象の文字列を探して、その終端のアドレスを格納するポインタのアドレスです
大抵は一回だけの変換で済むので、何処で終わりになろうが気になりません
だから大抵はNULLか空っぽのポインタ変数を指定するだけ
この回答への補足あり
    • good
    • 0

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