victorious_a
@victorious_a

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Atcoder beginners SlectionのPlacing Mablesについての質問

Atcoder beginners selectionの"Placing Marbles"という問題について、提出時になぜ警告が出るかがわからないので、アドバイスを頂けたら幸いです。
また、コードテストはpaiza.ioというブラウザ上でコードが書けるものを使用しているのですが、そこではエラーも警告もなく実行出来ました。これについても、なぜそうなるのか教えていただけると幸いです。

(以下、提出コード)

include

int main (void){
int s1,s2,s3 ;

scanf("%d,%d,%d",&s1,&s2,&s3);

int sum = s1 + s2 + s3 ;

if (sum == 0){
printf("どのマスにもビー玉はありません");
}
else if (sum == 1){
printf("置かれたビー玉の数は%dです。",sum);
}
else if (sum == 2){
printf("置かれたビー玉の数は%dです。",sum);
}
else if (sum == 2){
printf("置かれたビー玉の数は%dです。",sum);
}
return 0 ;
}

(以下、コンパイルエラー)
./Main.c: In function ‘main’:
./Main.c:6:1: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
6 | scanf("%d,%d,%d",&s1,&s2,&s3);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0

3Answer

scanf の関数定義を見ると、おそらく以下のようになっていると思います(バージョンなどによって違うかもしれませんが)

int scanf(const char *format, ...);

戻り値として、int 型の情報が返ってきます(入力項目数が返ってくるはず)

コンパイラの設定などにもよるのですが、(バグを見つけやすくするために)チェックを厳しめにしていると、この手の値を返す関数の値を使っていない場合に、「値を使っていないけど、大丈夫?」という警告を出してくれます。
(コンパイラの種類や、設定内容によっては何も出ないことがあります)

警告を出さないようにするにはいくつか方法があります。

  • 戻り値を取得して、使用する
  • 戻り値を無視することを明記する。一般的には void にキャストします。 (void) scanf("%d,%d,%d",&s1,&s2,&s3)
  • 設定を変えて、警告を出さないようにする

また、コードテストはpaiza.ioというブラウザ上でコードが書けるものを使用しているのですが、そこではエラーも警告もなく実行出来ました。これについても、なぜそうなるのか教えていただけると幸いです。

前述のように、環境によって警告を出すものと、出さないものがあります。

1Like

Comments

  1. @victorious_a

    Questioner

    回答ありがとうございました。上記の方法を試したら、無事実行できて、警告も消えました。

scanfの戻り値を使用しているか、ということです。

scanfは成功した場合、読み取りに成功した入力の数を返し、失敗した場合、EOF(-1)を返します。

例:

#include <stdio.h>

int main (void) {
    
    int s1, s2, s3 = 0;
    
    int result = scanf("%d,%d,%d", &s1, &s2, &s3);
    
    if (result == EOF) {
        printf("scanfに失敗しました。\n");
        printf("result: %d\n", result);
        
        return -1;
    }
    
    printf("scanfに成功しました。\n");
    printf("result: %d\n", result);
    printf("s1: %d\n", s1);
    printf("s2: %d\n", s2);
    printf("s3: %d\n", s3);
    
    return 0 ;
}

例えば、入力が1,2,3だった場合、scanf は成功し、読み取りに成功した入力の数として3が返ります。

scanfに成功しました。
result: 3
s1: 1
s2: 2
s3: 3

入力が1,2,だった場合、scanfは成功しますが、読み取りに成功した入力の数は2になります。

scanfに成功しました。
result: 2
s1: 1
s2: 2
s3: 0

そして、入力が無かった場合、scanfは失敗し、EOFを返します。(paizaの場合、入力の欄に何も書かない場合、こうなりました。)

scanfに失敗しました。
result: -1

質問者さんが掲載されたコードでは、上記のようにscanfの戻り値の結果が確認されていないため、件の警告が出たと思われます。

1Like

Comments

  1. @victorious_a

    Questioner

    何度も丁寧に説明していただきありがとうございました。おかげで理解でき、警告も消えました。

scanfの戻り値をチェックしないと、その警告が出るらしいです。

警告について

scanfの戻り値について

0Like

Comments

  1. @victorious_a

    Questioner

    ”戻り値のチェック”というのがわからないです。素人質問で申し訳ないですが、もしよければ教えていただきたいです。

Your answer might help someone💌