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

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

ただいまの
回答率

88.23%

文字列内の指定部分文字の出力について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 173

ray_natsuki

score 8

PHPでの指定部分文字の出力について

標準入力で下記の文字列と数値が与えられます。
abcdefg;
1 4;
2行目の数値の部分の文字を出力しなさい。
回答 abcd

現在、問題集でこの問題に取り組んでいます。
まずは$numをstr_replaceで半角スペースを,に置換して変数$nに代入。その後はsubstrだと思いコードを書いてみるものの、うまくいきません。
1 4なのに回答がabcdとなっているのでどこかの段階で-1を付けるのだろうとは思うのですが……。

試した事

$str = trim(fgets(STDIN));
$num = trim(fgets(STDIN));
$n = str_replace(' ', ',', $num);
echo substr($str, );

エラーメッセージ

PHP Notice:  A non well formed numeric value encountered in /workspace/


本来数値(1, 4)を入れるべきところへ変数($n)を入れると上記のエラーが出ます。
しかしそうするとbcdfと出力され、回答通りにいきません。
しかし、これ以上の方法が思いつきません。
よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • hentaiman

    2020/12/28 00:41

    せめてsyntaxエラーの無いコード、コード記載用のマークダウンの利用(回答してくれる人たちがコピペで再現出来るように)、期待する結果と現状の結果の記載など、最低限質問文を整えましょう

    キャンセル

回答 2

+1

$num = 1 4;
が、syntax error となるはずなので、問題として破綻しているかと。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/12/28 01:17

    回答ありがとうございます。
    問題を確かめてみましたが、何度見てもああなっています。
    本当に初心者で、質問の仕方も心得ておらず、すみません。

    キャンセル

  • 2020/12/28 01:25

    標準入力の事を書き忘れていました。申し訳ありません。

    キャンセル

checkベストアンサー

0

こういう働きをするプログラムを得たいのではないかと思います。 まずはそのまま試してみてください。
<?php $str = trim( fgets( STDIN ) ); $numstr = trim( fgets( STDIN ) ); preg_match( "/([0-9]*)[^0-9]*([0-9]*)/", $numstr, $numstrs ); if ( count( $numstrs ) > 2 ) {     $s = mb_substr( $str, intval( $numstrs[ 1 ] ) - 1, intval( $numstrs[ 2 ] ) );     echo $s; } ?>

preg_match() は、正規表現で文字列の照合をしてくれる便利関数です。 第1引数が正規表現、第2引数が元の文字列、第3引数が結果の入る変数です。
今回の場合、'1 4;' という文字列から、1 と 4 という2つの数字を別々に抜き出す必要がありますが、こういう時は正規表現が便利です。

もしかすると題意は「標準入力を1文字ずつ読み取って数字を取り出すプログラムを書け」なのかも知れませんが(行末のセミコロンが「その匂い」を漂わせている)、ちょっと面倒そうです。
そこで本回答では、指定数字の入った文字列を「数字の連続」「非数字の連続」「数字の連続」という3つの部分に分けて照合し、「数字の連続」だけを取り出すようにしました。

PHP の正規表現で ( ) を使うと、「合致する部分」を要素に持つ配列が得られます。 '1 4;' を与えた場合、$numstrs[0] は元の文字列である '1 4;'、$numstrs[1] は '1'、$numstrs[2] は '4' になります。
後は、得られた2つの数字列を数値にして mb_substr() するだけです。 mb_substr() の第2引数で -1 するのは、質問者様がお考えの通りです。

なお、substr() は文字列をバイト単位で扱うので、場合によっては注意が必要です。 文字数単位で扱う mb_substr() の方が(処理はたぶん重いが)、予期せぬ間違いは少ない、と思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/12/29 20:35

    お世話になります。丁寧な回答と解説、ありがとうございます。
    まだ勉強不足な部分も多いのですが、試させていただいたところ、うまくいきました。
    助かりました。本当にありがとうございました。

    キャンセル

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

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

関連した質問

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