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

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

ただいまの
回答率

90.51%

  • C

    4517questions

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

  • C++

    4423questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

atoi関数を自作する

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,421

strike1217

score 568

int strtoi(char *str){
    int num = 0;

    while(1){
        if(*str>='0' && *str<='9'){
            if(*str == 0)
                break;
            else {
                num = num * 10 +(*str - '0'); // 文字数字変換
                str++;
            }
        }
        else{
            num = 0;
            break;
        }
    }
    return num;
}


数字と文字の判定を行うところがおかしいようです。

if(*str>='0' && *str<='9')ここがうまくできていないようです。
・・・?
なぜでしょうか??

if( (*str>='a'&& *str<='z') || (*str>='A' && *str<='Z'))
こちらはうまくできます。

どうしてか理由が分かりません。
どなたか教えてください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2017/05/29 14:57

    「うまくできていない」を説明せよ。

    キャンセル

回答 4

+2

ループを抜ける際に、下のelseに入るので、必ずnum = 0にリセットされてしまいます。if(*str>='0' && *str<='9')の条件がある以上、上のif(*str == 0)に入ることはありません。

なお、本来のatoiは先頭から見て数字として読めるところまでを返す、つまり"123abc"なら「123」が返る、とのことです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/29 14:51

    while文のループを抜けたときに、elseに入ってしまうということですか??

    キャンセル

  • 2017/05/29 15:11 編集

    上のif-breakに入ることがない→下のelseでしかループを抜けられない、ということです。

    キャンセル

checkベストアンサー

+1

if(*str == 0)
これの場所が悪いですね。

if(*str>='0' && *str<='9'){
これの中に書いてあるので、そもそも使われないコードです。
よって*str == 0の場合は、最後のelseに入ってしまい、常に0が返っています。

こうしてみましょう。

int strtoi(char *str){
    int num = 0;

    while(1){
        if(*str == 0){
            break;
        }
        else if(*str>='0' && *str<='9'){
            num = num * 10 +(*str - '0'); // 文字数字変換
            str++;
        }
        else{
            num = 0;
            break;
        }
    }
    return num;
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/29 15:01

    if(*str == 0)
    break;

    がelseの中に入ってしまうんですか?

    キャンセル

  • 2017/05/29 15:03

    そうです。
    if(*str>='0' && *str<='9')
    この条件は'0'~'9'なので、そもそもNULL文字は一致しません。
    なので、elseの方に行ってしまいます。

    キャンセル

  • 2017/05/29 15:07

    ああ~~~
    そうですね!
    最後に必ずNULL文字があるので、文字列の最後のNULL文字がやってきたら、必ずelseの中に入って0になってしまうんですね!!

    キャンセル

  • 2017/05/29 15:09

    そゆことです。

    キャンセル

  • 2017/05/29 15:29

    break;の有効範囲は1スコープ(1つの{})内ですか?
    それとも、breakを使ったら、たくさんの入れ子スコープであっても即while文を抜けるのでしょうか??

    キャンセル

  • 2017/05/29 15:33

    一番内側のループにのみ有効です。
    while(1){
     while(1){
      break; // (1)へ
     }
     // (1)
     break; // (2)へ
    }
    // (2)

    キャンセル

  • 2017/05/29 15:35 編集

    while(1){
    if(){
    if(){
    break;
    }
    }
    }

    この場合のbreakはwhile文を即抜けますか??

    キャンセル

  • 2017/05/29 15:37

    抜けます。
    疑問に思ったら簡単なコードを書いて動かしてみるといいですよ。

    キャンセル

  • 2017/05/29 15:39

    わかりました。
    breakはスコープ単位ではなく、ループ単位なのですね!

    キャンセル

0

  if(*str>='0' && *str<='9'){ ← これが真であるなら
    if(*str == 0) ← この評価式は常に偽となるので
      break;      ← breakされることがなく、結果的に while-loop を抜け出せない
    else {
    ...

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

if(*str>='0' && *str<='9'){


が問題なのではなく

else{
  num = 0;
  break;
}


によってそれまでせっかく計算してきた結果が0で上書きしてから終了しているのが問題という事では無いでしょうか

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

同じタグがついた質問を見る

  • C

    4517questions

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

  • C++

    4423questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。