PHPで修行中の者です。


csvを開いて編集し、同じディレクトリに別名保存するphpを作ろうしましたがよく分からなくなりギブ。

やりたいことは以下です
moto.csvを

aaa,0.3,コメント01
bbb,0.4,コメント02
ccc,0.5,コメント03

2行目数字の部分を2倍し、コメントを削除してato.csvに格納です。

ato.csv
aaa,0.6
bbb,0.8
ccc,1

$Data=file('moto.csv');
for($i=0;$i<sizeof($Data);$i++){
$line=explode(",",$Data[$i]);

$name = $line[0];
$number = $line[1];
$sum = 2 * $number;

みたいな感じなのか、色々ネットサーフィンしたんですがよく分かりませんでした。
助けてくださいませ。

回答の条件
  • 1人50回まで
  • 登録:
  • 終了:2013/07/03 12:10:27

ベストアンサー

id:tobeoscontinue No.3

回答回数220ベストアンサー獲得回数59

$ato = '';
$Data=file('moto.csv');
foreach ($Data as $data) {
  $line=explode(",",$data);
  if (count($line) == 3) {
    $name = $line[0];
    $number = $line[1];
    $sum = 2 * $number;
    $ato .= $name.",".$sum."\n";
} }
file_put_contents("ato.csv", $ato);

多少コードを変更して各行ごとの処理をしたものを$atoの文字列に結合していって最後にfile_put_contentsで出力するようにしました。
配列をforで回す場合はforeachを使った方がベターだと思います。
if (count($line) == 3)
はcsvファイルに空文があった場合への対処です。場合によっては違う条件にする必要があるでしょう。

各行ごとにその都度出力するのであればループの中で
file_put_contents("ato.csv",$name.",,".$sum."\n",FILE_APPEND);
とすれば可能ですが追記なので最初に削除の処理を入れる必要があるように思います。

$in = fopen("moto.csv", "r");
$out = fopen("ato.csv", "w");
while (($line = fgetcsv($in, 1000, ",")) !== FALSE) {
  if (count($line) == 3) {
    $line[1] *= 2;
    array_pop($line);
    fputcsv($out, $line);
  }
}
fclose($in);
fclose($out);

csvを扱う場合はfgetcsv,fputcsvを使ったほうが可読性がいいように思います。
array_popは配列から最後の要素を取り去ります。この場合はコメントを削除することになります。
仮に配列の途中にあるものを削除する場合はarray_spliceが使えます。

id:admn

tobeoscontinue様本当にありがとうございました。
貴重なお時間裂いて頂き感謝です。

答えを書いて頂き、自身で逆引きできました。
PHP、csvの変換の為に活用始めたばかりなので助かりました。

また、何時か何処かで宜しくお願いします。

2013/07/03 12:10:18

その他の回答2件)

id:TransFreeBSD No.1

回答回数668ベストアンサー獲得回数268

そんな感じであってます。
あとはカンマでつなげてファイルに書いていくだけです。
ファイルへの書き込みは file-put-contents で良いんじゃないですか。
http://jp.php.net/manual/ja/function.file-put-contents.php
これで一行毎に書いていくと効率悪いですが、とりあえず練習はそれでいいと思います。

あとは結果を変数に詰め込むとか、配列を直接書き換えるとかして、最後に一気に書くとか、さらに読み書きを一行ずつやっていくとか色々やり方があるので、じっくりやれば修行できますよ。
頑張ってください。

id:admn

質問者から

admn2013/07/03 11:37:06

忙しい中、ご返答ありがとうございます

その先の

file-put-contents

出し方がなんだか分からないのです。

出力しても『1』だけだったり、数列の一行目の一文字を摘んで出力されたりと、

どなたかお知恵をお貸し下さいませ。

id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268

追記の設定で書いていますか?
http://jp.php.net/manual/ja/function.file-put-contents.php

filename が存在しない場合はファイルを作成します。 存在する場合はそのファイルを上書きします。ただし FILE_APPEND フラグが設定されている場合は別です。

「例2 フラグの使用」も参照。

あと、聞くときはコード全体を出してください。ダメな理由を聞くのにダメなコードがなければ話になりません。

id:tobeoscontinue No.3

回答回数220ベストアンサー獲得回数59ここでベストアンサー

$ato = '';
$Data=file('moto.csv');
foreach ($Data as $data) {
  $line=explode(",",$data);
  if (count($line) == 3) {
    $name = $line[0];
    $number = $line[1];
    $sum = 2 * $number;
    $ato .= $name.",".$sum."\n";
} }
file_put_contents("ato.csv", $ato);

多少コードを変更して各行ごとの処理をしたものを$atoの文字列に結合していって最後にfile_put_contentsで出力するようにしました。
配列をforで回す場合はforeachを使った方がベターだと思います。
if (count($line) == 3)
はcsvファイルに空文があった場合への対処です。場合によっては違う条件にする必要があるでしょう。

各行ごとにその都度出力するのであればループの中で
file_put_contents("ato.csv",$name.",,".$sum."\n",FILE_APPEND);
とすれば可能ですが追記なので最初に削除の処理を入れる必要があるように思います。

$in = fopen("moto.csv", "r");
$out = fopen("ato.csv", "w");
while (($line = fgetcsv($in, 1000, ",")) !== FALSE) {
  if (count($line) == 3) {
    $line[1] *= 2;
    array_pop($line);
    fputcsv($out, $line);
  }
}
fclose($in);
fclose($out);

csvを扱う場合はfgetcsv,fputcsvを使ったほうが可読性がいいように思います。
array_popは配列から最後の要素を取り去ります。この場合はコメントを削除することになります。
仮に配列の途中にあるものを削除する場合はarray_spliceが使えます。

id:admn

tobeoscontinue様本当にありがとうございました。
貴重なお時間裂いて頂き感謝です。

答えを書いて頂き、自身で逆引きできました。
PHP、csvの変換の為に活用始めたばかりなので助かりました。

また、何時か何処かで宜しくお願いします。

2013/07/03 12:10:18

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません