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

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

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

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

Q&A

解決済

2回答

1602閲覧

strlen関数 変換指定子%dでprintfできないのは何故でしょうか

kou09010901lam1

総合スコア1

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

0グッド

0クリップ

投稿2021/05/03 15:10

前提・実現したいこと

書籍の復習問題にてstrlen関数をprintfで出力する際の変換指定子が書籍では%dとなっているのですが、実際コンパイルするとエラーが起き 
エラー文通りに変換指定子を%luにすると改善されました。書籍は2017年製のものでしたが、今はC言語の仕様が変化しているのですか?
エディタはVImでGCCでコンパイルしています。

発生している問題・エラーメッセージ

hukusyuu.c:7:37: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat] printf("str1の長さは%dです\n",strlen(str1)); ~~ ^~~~~~~~~~~~ %lu 1 warning generated.###

C

1char str1[100] = {'h','e','l','l','o','\0'}; 2char str2[] = "C_gengo" ; 3printf("str1の長さは%dです\n",strlen(str1)); 4 5strcat(str1,str2); 6 7printf("str1に格納されている文字は%sです\n",str1);``` 8 9### 試したこと 10Googleで検索しました 11### 補足情報(FW/ツールのバージョンなど) 12vim version 8.2.1972

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

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

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

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

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

Milly

2021/05/05 08:00

Vim には関係しない質問のようです。 質問について検索する人の邪魔になるのでVimタグを外したほうがよいでしょう。
guest

回答2

0

strlen の返却値の型は size_t ですが、これは符号無し整数であることしか言語仕様では定められていません。 言語仕様の範囲内で処理系・実行環境の都合に合わせて選択することを許すように幅がある仕様なのです。 unsigned int 相当である場合もありますし、 unsigned long int 相当ということにしている処理系もあります。

size_tunsigned int 相当である環境では printf でもそれが unsigned int であるかのように扱って良く、実際にそういう環境がかなり多かったことから古い資料ではそれを前提にしていることがよくあります。

しかし、 64bit 環境が主流になり、 64bit の都合に合わせた処理系が出てくるようになると前提が変わってきました。 size_tunsigned int 相当でない場合が多くなってきたのです。 そして今回の質問者の例では size_tunsigned long int 相当であることを選択した処理系なのでしょう。

言語仕様的に言えば、書式指定が %d である (int を期待する) ところに unsigned long int を渡した場合の挙動は未定義です。 (「既定の実引数拡張」について検索してみてください。) そして諸事情から可変長引数の関数は型チェックが緩く、間違っていても正確に捕捉できないことがあります。

C99 以降においては size_t に対応する書式指定として %zu が用意されていますので、それを使うのが妥当です。

つまり、質問に対して端的に言えば「言語仕様は元から選択の幅があった」ということです。

投稿2021/05/03 15:47

SaitoAtsushi

総合スコア5684

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

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

0

ベストアンサー

strlenの返り値は size_t で C89 から変化してないようです。

上のメッセージは、 warning のみのようです。エラーならコンパイルに失敗しますが、
warningなら コンパイル自体は成功するので、最近のコンパイラのwarningが増えているか
本の作者があまり気にしてなかったとかでしょうか。

投稿2021/05/03 15:17

hide5stm

総合スコア426

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

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

maisumakun

2021/05/03 22:44

仮に「warningのみ」であったとしても、intとsize_tの幅が違う環境では正常に動作しないと思われます。
hide5stm

2021/05/04 01:36

本の著者の環境は32bitsだったので問題はなかった。というのはありそうですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問