No.1
- 回答日時:
可能です。
下記サンプルをお試しください。open FILE, "hoge.txt" or die 'ファイルが開けません。';
@data = ();
while (<FILE>) {
chomp;
push @data, [ split /\s+/ ];
}
close FILE;
print $data[0][0]; # A
print $data[0][1]; # 1
print $data[1][0]; # B
print $data[1][1]; # 2
・ファイルの読み込みでは、foreach ではなく、while を使います。foreach でも出来なくはないのですが、効率がよくありません。
・while (<FILE>) で読み込んだデータは、特殊変数 $_ に入ります。引数を指定しない chomp や split では、この $_ が対象となります。
・[ split /\s+/ ] では、空白区切りで分割したデータのリストを初期値として、無名配列を生成しています。配列の要素が配列となるので、2次元配列として使用することが出来ます。
No.2
- 回答日時:
> 行数と列数を@dataから取得する方法があればおしえてください。
行数は
$rows = @data;
列数は
$cols = @{$data[0]};
で取得できます。
ただし、「列」の部分については「無名配列」を使って動的に生成しているので、ファイル内容に不備があると、行ごとの列数が一定でなくなってしまいます。
例えば、万が一
hoge.txt
A 1
B 2 7
C 3
なんてことになっていたりすると、2次元配列の内容も同じように
行\列 0 1 2
0 A 1 なし(列数2)
1 B 2 7 (列数3)
2 C 3 なし(列数2)
のようになってしまいますので、ファイルの生成には注意が必要です。
※Perlには、C言語などのような「完全な2次元配列」を定義する方法がなく、「配列の各要素に別の配列を割り当てる」という方法で実現しているため、このような問題が起こり得ます。
この回答への補足
どうもありがとうございます。
ただ、作成しているものがどうしてもうまくいきません。ご助言いただければうれしいです。
2次元のテーブルファイルから全ての行を取得したり、指定した行を取り出すようなクラスを作りたいと思っています。new()では、指定したファイルのデータを全て2次元の配列に格納します。そして、メソッドでnew()で格納したデータを取得して処理をしたり、指定行を取り出すといった処理をしようと思います。しかし、sub側やmain側でnew()で格納したデータの値を取得することができません。
例えば
package Table;
#コンストラクタでは、指定したファイルをオープンしてデータを2次元の配列に格納しておきます。
sub new {
my($this) = shift;
my($file) = shift;
my(@data) = ();
my($rows) = 0;
my($cols) = 0;
my($fh) = new IO::File;
if ($fh->open("$file")) {
while (<$fh>) {
chomp;
push @data, [ split /\s+/ ];
}
$fh->close;
} else {
エラー処理
}
$rows = @data;
$cols = @{$data[0]};
my($tbl) = {"name" => "$file",
"data" => "@data",
"rows" => "$rows",
"cols" => "$cols"};
bless $tbl, $this;
}
#get_data()でデータを取得する
sub get_data(){
my($this) = shift;
return $this->{data}
}
sub get_rows() {
my($this)->shift;
my($indx) = shift;
my($key) = shift;
#$this->{data}から値を検索したいが$this->{data}からうまく値を取得できない。
}
package main;
my($tbl)->new Table "File";
my(@data) = $tbl->get_data();
#@dataを使って行ごとの処理とか指定した列の値を使って処理したい。
No.3ベストアンサー
- 回答日時:
> ただ、作成しているものがどうしてもうまくいきません。
どう「うまくいかない」のか、がないのですが、スクリプトを解析して問題点を指摘して欲しい、ということでしょうか、、、
補足に書かれたスクリプトの問題点を挙げますので、参考にしてみてください。
・コンストラクタで IO::File を使っているが、use していない。
・get_rows の先頭と main 先頭での変数への代入式が誤っている。それぞれ
my($this)->shift;
↓
my($this) = shift;
my($tbl)->new Table "File";
↓
my($tbl) = new Table "File";
ちなみに、get_rows のように引数が複数ある関数では、
my ($this,$index,$key) = @_;
と書くことができます。
・オブジェクトの生成で、data の持ち方がおかしい(これが一番問題)。
"data" => "@data",
では、$tbl->{data} の内容は「リファレンス値を列挙した文字列」になってしまいます。ここでは配列データを持たせるべきなので
"data" => \@data,
とします。ダブルクォートは付けてはいけません。
こうすると、$tbl->get_data の戻値もリファレンスになるので、受け取る側は
my $data = $tbl->get_data;
のようにし、各要素へのアクセスは、
$data->[$row][$col]
のようにします。
まずはリファレンスについての理解を深めることを勧めます。
リファレンスについてのドキュメント
http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.h …
2次元配列の扱いに関するドキュメント
http://www.kt.rim.or.jp/~kbk/perl5.005/perllol.h …
参考URL:http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html,http://www.kt.rim.or.jp/~kbk/perl5.005/perllol.h …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- C言語・C++・C# C言語 2 2022/07/21 00:02
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Perl perlで2次元配列をサブルーチンに値渡しで渡す 5 2022/12/17 18:49
- Ruby 初心者プログラミング 3 2022/10/12 11:31
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列のサイズを動的に拡張
-
Pythonの再帰関数の動作の流れ...
-
文字列をカウントする方法
-
ファイル全てを .xlsm に変更し...
-
一定時間が経過したフォルダの削除
-
csvファイルの横方向への改行に...
-
while(<ハンドラ>) {} で行数を...
-
画像アップロード機能を追加し...
-
batファイルでrenameができませ...
-
while文がうまく動かない
-
VBAでCSVファイルの特定行を書...
-
MATLABのm-fileについて
-
ディレクトリのファイル作成を...
-
ANSI Cでファイル名、ディレク...
-
VB6.0でDB接続する際に切断時の...
-
AutoCADのスクリプト
-
C++でファイルから複数行のデー...
-
オープンしたファイルで行の連結
-
Perlで特定行から特定行までを...
-
連番のファイルを何個も開きたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列の中に重複文字列があるか...
-
C言語のバイナリモードでのfsca...
-
データの日付でソートをしたい
-
perlで複数行のデータを自由に...
-
perl-cgi 文字の長さでソートし...
-
Visual C++を用いたシリアル通信
-
バッチファイルの作り方(CSV→...
-
awkスクリプトでダブルクォーテ...
-
VBAでCSVファイルの特定行を書...
-
DOSコマンドで、標準出力を出力...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAでCSVファイルを途中行まで...
-
window.open でのファイル指定方法
-
VBAで巨大なファイルの途中から...
-
Perlで特定行から特定行までを...
-
ReadLineでの読み出し行を指定する
-
エクセルVBAで素数だけを出力す...
おすすめ情報