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

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

新規登録して質問してみよう
ただいま回答率
85.48%
標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

820閲覧

<PHP>for文、intを上手に使えない

nogish

総合スコア20

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2020/07/14 10:50

編集2020/07/16 02:00

前提・実現したいこと

paizaのレベルアップ問題集を解いています。
1行目でN人の従業員数を標準入力で取得し、2〜N+1行目でそれぞれの従業員の名前と、昨年の年齢を取得します。
期待される出力は、「従業員名 今年の年齢(昨年の年齢+1)」を全員分です。

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

実行結果ステータス:Runtime error 実行時エラーメッセージ: PHP Notice: Undefined offset: 1 in /workspace/Main.php on line 8 PHP Notice: Undefined offset: 1 in /workspace/Main.php on line 8 PHP Notice: Undefined offset: 1 in /workspace/Main.php on line 8 … が繰り替えされる 実行結果:Yamada 31 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 … 1が繰り返される。

該当のソースコード

PHP

1 $N = fgets(STDIN); 2 for ($i = 1; $i = $N; $i++) { 3 $employee_{$i} = explode(" ", fgets(STDIN)); 4 $age_{$i} = (int)$employee_{$i}[1] + 1; 5 echo $employee_{$i}[0]." ".$age_{$i}; 6 break; 7 }

試したこと

先日教えていただいた(int)を使って、解決できるかと思ったのですが、うまくいきませんでした。
また年齢は足されているのに、その後1が文字列として結合されているのでbreak;で止めれば良いのかと思ったのですが、3行目以降の出力も止まってしまいます。

また超初心者的な内容で申し訳ないですが、ぜひよろしくお願いいたします。

補足

追記以来でご指摘いただいた点を補足します。
こちらの問題はpaizaというサイトのpaizaラーニングにある、レベルアップ問題集のものです。
レベルアップ問題集を開くと、トップに

「このコーナーでは、プログラミングスキルを伸ばしたい方向けに問題セットを用意しました。
プログラムを書けるようになるための一番の近道はたくさんコードを書くことです。
自分の実力や目的に合わせて問題を選び、レベルアップを目指しましょう。
なお、このコーナー内の問題については、ユーザー同士で解答を教え合ったり、コードを公開したりするのは自由としています。
授業や研修にもご利用いただけますので、ぜひ教材などにもお使いください。」

(以下URL↓)
https://paiza.jp/works/mondai

とありますので、paizaで有名なスキルチェックとは性質が異なることがわかります。
SNS等の質問は大丈夫です。
ぜひご回答お願いします!!

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

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

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

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

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

maisumakun

2020/07/14 11:00

> paizaのレベルアップ問題集を解いています。 それは、第三者に質問して問題ない性質のものなのでしょうか?
nogish

2020/07/14 14:21

一応スキルチェックではなく、問題集なので大丈夫だと思います! 「このコーナー内の問題については、ユーザー同士で解答を教え合ったり、コードを公開したりするのは自由としています。」 こんな記述もあるのでおそらく!
m.ts10806

2020/07/14 20:32 編集

「思います」「おそらく」じゃなく、根拠を明示してください。
nogish

2020/07/15 03:31

申し訳ありません。 「このコーナー内の問題については、ユーザー同士で解答を教え合ったり、コードを公開したりするのは自由としています。」 これでは、根拠は不十分でしょうか、、?
m.ts10806

2020/07/15 03:55

それがどこに書いてあるのかを質問本文に明示してください。 今の状態では質問者さんの解釈によるコメントのみで、事実を確認できません。
nogish

2020/07/15 16:22

かしこまりました!ご指摘ありがとうございます!
javahack

2020/07/15 17:15

根拠を示す場合はURLを張らないと確認がとれません。 URLを追記してください。
m.ts10806

2020/07/15 21:18

「どこに書いてあるか」と聞いてるのに…
maisumakun

2020/07/16 02:01

> これですが、皆さんログインをしなければ見れないのではないでしょうか 中身は確認していませんが「自由」と書かれた部分は見えました。ありがとうございます。 (ログアウト状態を確認したい場合、プライベートブラウザを使うと便利です)
nogish

2020/07/21 06:17

ご確認ありがとうございます!プライベートブラウザも使ってみます
guest

回答1

0

ベストアンサー

たとえば入力が次のとおりだったとしましょう。

plain

13 2Alice 42 3Bob 43 4Charlie 43

for ($i = 1; $i = $N; $i++) {
このfor文の書き方では、2つ目の式 $i = $N によって $i には 常に $N が入ります。
つまり、 for ($i = 1; "3\n"; $i++) { となります。
for文は2つ目の式が true の限り実行されますが、文字列 "3\n"true ですので、 常に実行条件を満たしてしまい無限ループになります。
ループの1回目から3回目は fgets() によって各行が取得されますが、4回目になると fgets()false を返すようになります。

返り値

handle で指定したファイルポインタから最大 length - 1 バイト読み出し、 その文字列を返します。ファイルポインタから読み込むデータがもうない場合は FALSE を返します。
エラーが起こった場合、FALSE を返します。
PHP: fgets - Manual


つまりループの4回目において、
$employee_{$i} = explode(" ", fgets(STDIN));
$employee_{$i} = explode(" ", false); を意味します。

explode($delimiter, $string) において、第2引数は文字列である必要がありますので false は暗黙に文字列にキャストされます。 false を文字列にキャストすると空文字列 "" になります。
つまり、 explode(' ', '') です。
$employee_{$i} には 空文字列1つだけを内包する配列 [''] が入ります。


次の行、$age_{$i} = (int)$employee_{$i}[1] + 1; ですが、
$employee_{$i}[''] ですので、インデックス [1] にはアクセスできません。ここでNoticeが出ています
アクセスできないので、値は NULL が帰ってきます。つまり、 (int)NULL + 1 しています。
NULL を int にキャストすると 0 になります。
0+1なので $age_{$i} には 1 が入ります。


やっとここまで来ました。 echo $employee_{$i}[0]." ".$age_{$i}; ですが、

  • $employee_{$i}[0]''
  • $age_{$i}1

なので、結合すると、この行は echo ' 1'; ということになります。
先述のとおりfor文は無限ループになっていますので、 1 1 1 1 1 1 1 1 1 1... と無限に出力されます。

投稿2020/07/21 06:11

thyda.eiqau

総合スコア2982

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問