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

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

ただいまの
回答率

89.20%

【C言語】冗長だと思う数字入力プログラムを改善したい

受付中

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 1,562
退会済みユーザー

退会済みユーザー

以下のプログラムは3つの数字をスペース区切りで入力して、入力した数字を改行区切りで出力するというコードです。
C言語はあまり慣れていないので、以下のコードに冗長さを感じますが何か改善点はありますか?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    char inputNum[1000];
    int stock[3];
    char token[] = " ";
    char *tok;
    int count = 0;

    fgets(inputNum, sizeof(inputNum), stdin);
    tok = strtok(inputNum, token);
    while (tok != NULL) {
        stock[count] = atoi(tok);
        tok = strtok(NULL, token);
        count++;
    }

    for (int i = 0; i < sizeof(stock)/sizeof(stock[0]); i++) {
        printf("%d\n", stock[i]);
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

こんにちは。

3つの数字をスペース区切りで入力して、入力した数字を改行区切りで出力するというコードです。

要件がこれだけなら、私だったらお手軽に以下の感じです。

#include <stdio.h>

int main(void)
{
    int num0, num1, num2;
    if (scanf("%d %d %d", &num0, &num1, &num2) != 3)
    {
        fprintf(stderr, "input error\n");
        return 1;
    }
    printf("%d\n%d\n%d\n", num0, num1, num2);
}

処理する数値の数が増える可能性の有無や、改行が可笑しかった時どうするとか、周辺情報が見えないので、バランス点が見えません。
配列を使っても完全に無駄になる可能性を考慮すると、簡単確実なプログラムにしたいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/17 18:37

    ご回答ありがとうございます。
    そうですよね。やっぱりscanf使うんですね。
    fgetsだと他にもっと良いコードは書けないのでしょうか?

    キャンセル

  • 2017/07/17 18:57

    何を持ってして「良い」と言うのかが問題です。
    そのプログラムがどのように拡張されるのか、ある程度想定して、それに対応できるように設計されたプログラムは「良い」ものです。

    どんな作業をアシストするプログラムなのか見えないと、どのような拡張がありうるのか見当もつかないので、何か拡張できる仕組み(例えば配列とか)を仕込んでもまるっと無駄になるかも知れません。それは確実に「悪い」ものです。

    キャンセル

+1

むしろ短い。エラー処理まできちんとやりたいなら、相応の長さになる。

配列の境界チェック
atoi関数 => strtol関数
非常に長い入力への対処

どこまで簡潔に書けるか、というのは、どこまで仕様を詰めるか、で簡単に変わります。

ちなみに私なら(ズルして)、

標準入力を1文字ずつ読み込み、数字ならそのまま、空白なら改行、それ以外なら即リターンってコードします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/18 00:22

    ご回答ありがとうございます。

    キャンセル

0

whileループをちょいと書き換えてみました。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    char inputNum[1000];
    int stock[3];
    char token[] = " ";
    char *tok;
    int count = 0;

    fgets(inputNum, sizeof(inputNum), stdin);

    tok = strtok(inputNum, token);
    do { 
        stock[count] = atoi(tok);
        printf("%d\n", stock[count++]);
    } while(tok = strtok(NULL, token), tok != NULL);

    return 0;
}

こういうのもありかもしれませんね。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    char inputNum[1000];
    int stock[3];
    char token[] = " ";
    char *tok;
    int count = 0;

    fgets(inputNum, sizeof(inputNum), stdin);

    for(tok = strtok(inputNum, token); tok != NULL; tok = strtok(NULL, token), count++) {
        printf("%d\n", stock[count] = atoi(tok));
    }

    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/17 18:11

    ご回答ありがとうございます。

    キャンセル

  • 2017/07/17 18:12 編集

    ロジック自体に大きな変更はない感じですかね。

    キャンセル

  • 2017/07/17 18:18

    空白を改行に置き換えるのもありですが、そうするとstockが更新できないですからね...
    私はここまでです、他の回答の黒魔術っぷりに期待したいですね。

    キャンセル

  • 2017/07/17 18:36

    ありがとうございます。
    助かります!

    キャンセル

0

3つの数字をスペース区切りで入力して、入力した数字を改行区切りで出力
で作りました。改善点は?

#include <stdio.h>
#include <string.h>
#define NUM 3

int main(void) {
    char inputNum[1000];
    int stock[NUM]={'\0'};
    int i,j;

    fgets(inputNum, sizeof(inputNum), stdin);
    for (i=j=0;inputNum[i]!='\n';i++){
        if (inputNum[i]==' '){
           j++;
        }else{
           stock[j]=stock[j]*10+(inputNum[i]-'0');
        }
    }
    for (i=0; i<NUM; i++) {
        printf("%d\n", stock[i]);
    }
}

表示するだけなら

#include <stdio.h>
#include <string.h>

int main(void) {
    char inputNum[1000];
    char *p;
    p=inputNum;

    fgets(inputNum, sizeof(inputNum), stdin);
    while(p=strchr(p,' ')){
       *p='\n';
    }
    printf("%s",inputNum);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

#include <stdio.h>

int main(void){
  int i;
  char b[1000];

  fgets(b, sizeof(b), stdin);

  for(i = 0; i < 1000; i++){
    if(b[i] == '\0') break;
    printf("%c", b[i] == ' ' ? '\n' : b[i]);
  }

  return 0;
}


C初心者ですがやってみました。
数字かどうかの判定は行っていません。

#include <stdio.h>
#include <ctype.h>

int main(void){
  int i = 0;
  char b[1000];

  fgets(b, sizeof(b), stdin);

  while(b[i] == ' ' || isdigit(b[i])){
    printf("%c", b[i] == ' ' ? '\n' : b[i]);
    i++;
  }

  return 0;
}


数字の判定を入れたバージョン。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/18 07:26

    ご回答ありがとうございます。

    キャンセル

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

  • ただいまの回答率 89.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる