タイトルどおりなんですが・・・。

 Perlのサブルーチンに配列やハッシュを実体渡ししようとしたんですが,どうやってもできません.あきらめて,参照渡しにしたら,なんかうまくいっている模様です.

 これは,そもそも,はじめから参照渡ししか用意されていない、ということでしょうか?.それとも,何か実体渡しする方法があるのでしょうか?.

 後,余談なんですが,配列やハッシュの要素に別の配列やハッシュの実体を入れることはできるのですか?.これもちょっと試してみたらできなさそうだったのですが,あちこちのWebにある入門マニュアルみたいなページを見ても,その辺の話が「できる」とも「できない」ともほとんどの場合かいてなくて,自分の試し方が悪いのか,それとも無駄なことを延々とやっているのかがわからなくて疲れます.

このQ&Aに関連する最新のQ&A

A 回答 (6件)

■パラメータ渡しの仕組みについて



サブルーチンへのパラメータの渡され方ですが、まず、呼出側で指定したパラメータは1つのリストに展開されます。
そしてサブルーチン側では、そのリストの「別名配列」として @_ が用意されます。
@_ はパラメータリストの別名なので、$_[n] を操作することは、パラメータに指定した変数を直接操作していることと同じになります。
つまりPerlでは、常に「別名渡し」が行われます。
(即値やハッシュのキーのように別名が作れないものは、一時領域に値がコピーされ、その別名が渡るようです。)
ちなみにパラメータが即値である場合、変更しようとするとエラーになります。

■「値渡し」と「リファレンス渡し」について

サブルーチン側でのパラメータの操作を、呼出側の変数に反映させたくない場合は、パラメータを「値渡し」にします。
Perlでの値渡しは、サブルーチン側で用意した my(または local)変数に @_ の値をコピーすることで実現します。
また、呼出側の変数の値を操作したい場合でも、$_[n] の内容を直接編集することはあまりなく、普通はリファレンスを渡し、それをデリファレンスして値を操作します。
# 「実体渡し」とは、何が渡ることを望んでいるのでしょうか?

■複数の配列やハッシュの渡し方

パラメータは、全てが1つのリストに展開されるため、複数の配列やハッシュを渡したい場合は注意が必要です。
例えば、次のように2つの配列を渡しても、
  @x = qw(abc def);
  @y = (1, 2, 3);
  &f2(@x, @y);
  sub f2 {
    my (@a, @b) = @_;   # 2つの配列が欲しいのでこうしたが・・・
    print "a:[@a]\n";
    print "b:[@b]\n";
  }
 実行結果:
  a:[abc def 1 2 3]
  b:[]
1つ目の配列に、全て入ってしまいます。
これを回避するには、リファレンスを渡します。
  &f3(\@x, \@y);
  sub f3 {
    my ($a, $b) = @_;   # リファレンスはスカラーなので、$変数で受け取る。
    print "a:[@$a]\n";
    print "b:[@$b]\n";
  }
 実行結果:
  a:[abc def]
  b:[1 2 3]

■サブルーチンからの戻値について

サブルーチンからの戻値は、呼出時のコンテキストに依存します。
例えば、配列やハッシュ、リストを返していても、$変数で受け取っていたり、演算式に組み込んだりすると、それぞれに応じたスカラー値が返ります。
それ以外では、基本的にはリスト値が返ります。(配列やハッシュも、リストに展開されて返されます。)
どちらの場合でも、勝手に別名やリファレンスが返されることはありません。戻値は常に値渡しです。
# ハッシュは return できない、とありましたが、もちろんできます。

■配列とリストについて

とかく同じ物と思われがちですが、これらは別物です。
例えば、それぞれをスカラーコンテキストで参照すると、配列は「要素数」が返るのに対し、リストでは「最後の要素」が返ります。
また、当然ながらリストには変数領域がないので、暗黙に配列へのリファレンスを引数に取る push 関数などには、リストは渡せません。
リストはあくまで、その場限りのものです。

■無名配列、無名ハッシュについて

これらは、変数の必要なしに、配列やハッシュの中身をメモリ上に生成するものです。
無名配列は   [ リスト ]
無名ハッシュは { リスト }
として、生成します。
これらの値は、それぞれ「配列へのリファレンス」「ハッシュへのリファレンス」です。
> 配列やハッシュの要素に、別の配列やハッシュを入れる
というのは、この無名**を使います。(つまり、配列などの実体は入れられません。)
例えば、4×3の2次元配列は、次のように作ります。
  my @a = ( [0,1,2,3],[4,5,6,7],[qw(a b c d)] );
各要素を見るときは、
  foreach $row (@a) {
    foreach $val (@$row) {
      print "$val ";
    }
    print "\n";
  }
とか、
  foreach $r (0..2) {
    foreach $c (0..3) {
      print "$a[$r][$c] ";
    }
    print "\n";
  }
とします。

■No.4 の補足について
タイプミスかもしれませんが、
  sub subroutine {
    my $sch = $_[0];
    my $arr = @{ $_[1] };
    my $hsh = %{ $_[2] };
  }
これではダメです。
やるなら、
  sub subroutine {
    my $sch = $_[0];
    my @arr = @{ $_[1] };
    my %hsh = %{ $_[2] };
    $arr[0] = …
    $hsh{AAA} = …
  }
とするか、
  sub subroutine {
    my $sch = $_[0];
    my $arr = $_[1];
    my $hsh = $_[2];
    $arr->[0] = …
    $hsh->{AAA} = …
  }
とします。

分からない部分は補足してください。
    • good
    • 0

私が言ってる参照とリファレンスは別のものです。


リファレンスはそれ相当の構文が必要ですが、参照は暗黙のうちに参照先メモリ領域に代入します。

参照はC++で

int& x = variable;

と宣言したのと同じ、でリファレンスはCのポインタと同じで

int *y = &variable;

と宣言したのと同じです。
Cがわかんなかったらごめんなさい。


hoge($a);
sub hoge{
$_[0] = "ほげ";
}

のように、リファレンスの構文を使わなくても、暗黙に$aに代入されています。

もちろんリファレンスを使えば、配列やハッシュの変数も渡せますが、それでは構文が変わってしまうので、痛いと思ったのです。

>return %hash;
をすると、どうもリファレンスが返されてるような。

ちなみにリストと配列は同じものだと思います。

>それぞれへのリファレンスではなく,コピー実体が入ってそうな
コピー実態ではなく暗黙参照が入っています。
その変数をそのままプリントしても、アドレスが出るわけではなく、変数の値が表示されます。
しかし、その変数への代入は、参照先の変数を書き換えることになるのです。
そして、これができるのがサブルーチンスコープ内だけだということです。
return @_;して、それをサブルーチン外で受け取れば、参照が残っているような気もしますが、外に出たとたん参照は切れてしまいます。

$a = 5;
@ret = hoge($a);
print $a; # 10;
$ret[0] = 100; # 参照は切れてるので影響なし。
print $a; # 10
sub hoge{
$_[0] *= 2;
return @_;
}
    • good
    • 0

byval(@a)と書くと($a[0..$#a])を渡したのと同じになります。


リファは入ってません。
しかし、@_は@aの参照ではありません。
$_[0]から$_[$#a]が$a[0]から$a[$#a]の参照なのです。
だから内部で@_=@otherとか代入しても、関係ないです。
また、それぞれが参照である期間は、サブルーチンスコープ内のみです。
これはVisual BasicやJAVAなど、参照で引数を取るタイプの言語としては標準の動きみたいです。

ちなみに自作サブルーチンに渡す引数は、全部リスト扱いです。
(@a, 5, 6, 'ほげ')とかリスト表現できるように、それをサブルーチンに渡してるだけです。

ちなみにbyval(%hash)したら、さすがにハッシュリファが渡ってしまいました。
また、ハッシュ自体をreturnできそうもないので、これもまた考え物です。

この回答への補足

 がーん.

 えーっと,俺様なんだか激しくマチガイ理解の予感が・・・.
 ちょっ,ちょっとまってくださいね.

 今,僕は,

sub subroutine{
 my $sch = $_[0];
 my $arr = @{ $_[1] };
 my $hsh = %{ $_[2] };
}

 とやっておけば,

&subroutine( $sch, \@arr, \%hsh );

 とやったときに,ローカルスコープの変数へそれぞれちゃんとコピーできるのではないか,と理解しているのですが,これは間違っていますか?.

 それと,ハッシュをreturn出来ない,と言うのは,サブルーチン内で

 return %hsh;

 と言うのが出来ない,と言うことですか?.

 また,僕はいまいちリストコンテキストと言う物が理解できなかったのですが,ここを読んでるうちに一つ思ったことがあります.次のような物ですが,これはまた間違っているでしょうか?,またどこが間違っているでしょうか?.

 つまり,データ構造としては「リスト」,「配列」,「ハッシュ」があり,それぞれ,

( e1, e2, e3 );
[ e1, e2, e3 ];
( 'k1' => e1, 'k2' => e2, 'k3' => e3 );

 のような記法で表現できる.ここで,@変数にリストの記法で代入を行うと,配列が生成され,%変数にリストの記法で代入を行うと,偶数番要素がキー,奇数番要素が要素となるハッシュが生成される.
 同様にリストの記法の左辺に@変数を代入すると,右辺の配列の要素と同じ値を要素とするリストが生成され,代入される.
 分けわかんなくなって来てますが,よろしくお願いします.

補足日時:2002/03/26 12:25
    • good
    • 0
この回答へのお礼

 まず,ありがとうございます(笑).

 補足を書いてから気がついたので,ここに書かせていただきます.

 ひょっとして,サブルーチンの引数に配列を指定すると,(引数はリストコンテキストなので)配列がリストに展開されて,配列の要素分の引数がサブルーチンに引き渡される,と言うことですか?.とすると,

> $_[0]から$_[$#a]が$a[0]から$a[$#a]の
> 参照なのです。

 とはいいますが,$_[0]から$_[$#a]には$a[0]から$a[$#a]それぞれへのリファレンスではなく,コピー実体が入ってそうな気がするんですが・・・.
 ちょっと今,実験できる環境ではないので,帰ってから実験してみます.

お礼日時:2002/03/26 12:51

英語なんですが


perldoc perldsc
とすれば全パターンのってます^^
(配列の配列、配列のハッシュ、ハッシュの配列、ハッシュのハッシュ)×(静的、動的)

駱駝本(ProgrammingPerl)第2版の4.7に翻訳があります。

Hash Of Hashであれば、
# print the whole thing
foreach $family ( keys %HoH ) {
print "$family: { ";
for $role ( keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
こんな感じにやるようです>perldscからの引用です。
書くと大変なので、一度読んでみてください^^

横やりですが
>出来ないはずの配列の実体渡しという
たぶん、元の配列のコピー(テンポラリ)への参照なので、「一見実体渡しのように見える参照渡し」では無いでしょうか?(推測)
トリッキーな印象を受けるので、先頭でコピーする方が一般的で良いんじゃないでしょうか^^
sub hoge {
my ($arg1, $arg2, ... , $argN) = @_;
...
}
    • good
    • 0

関数の戻り値や式の結果は値渡しされます。



@a = (5, 6, 7, 8, 9);
print "初期値\n";
print '@a = '; print "$_ " foreach(@a); print "\n";
hoge(byval(@a));
print "hoge(byval(\@a));しました\n";
print '@a = '; print "$_ " foreach(@a); print "\n";
hoge(@a);
print "hoge(\@a);しました\n";
print '@a = '; print "$_ " foreach(@a); print "\n";

sub hoge($){ $_ *= 2 foreach @_; }
sub byval{ return @_; }

Visual Basicみたいな構文になりました。

動作環境: W2K+ActivePerl5.6

えーと、ハッシュの場合は考えてないです。
応用してください。

この回答への補足

 なるほど,返り値はコピー実体なので,引数をそのまま返す関数を作って,ワンクッションおくと言うことですか?.

 しかし,書いていただいたソースがよく分らなかったのですが,byval()関数が返す実体は,先頭要素に与えた配列へのリファレンスが入っているような配列になりませんか?.
 しかもそのままそれをhoge()関数に与えると,出来ないはずの配列の実体渡しという事になりませんか?.

補足日時:2002/03/25 12:28
    • good
    • 0

 最新のPerlはわかりませんが、(少なくとも初期の)Perl5では参照渡しか出来ないはずです。


 駱駝本第2版「2.7 サブルーチン」を読んだ限り、「my で宣言されたローカル変数に、コピーすることで値渡しを実現する」ようです。

>配列やハッシュの要素に別の配列やハッシュの実体
できます。
とりあえず、静的には
@AoA = ( # 配列の配列
["foo1", "bar1"],
["foo2", "bar2"],
["foo3", "bar3"],
);
やら
%HoA = ( # ハッシュに配列
first => ["foo1", "bar1"],
second => ["foo2", "bar2"],
third => ["foo3", "bar3"],
);
でできます。[LIST] のような形で配列が得られるようです。

この回答への補足

 早速の御回答ありがとうございます.
 昨日確かに補足を投稿したと思うのですが,消えてなくなっています.おかしいと思いつつもう一度投稿させていただきます.

 即値を代入できることは分りました.ありがとうございます.また,これをアクセスする方法もいろいろやってるとわかりました.

 ただ,次のような代入が可能なのかどうか教えて欲しいです.

 @AoH = ( %hash1, %hash2 );

 あるいは,この逆など(%HoAや%HoHへの代入)は可能なのでしょうか?.
 また,可能であるとして,どの様にアクセスすればいいのでしょうか?.とりあえず,代入の時点でエラーは出ないのですが,参照しようとしても,

 foreach $key ( keys( %HoH ) ){

 のなかでは,

  %H = $HoH{$key};

 としても,

  %H = %{ $HoH{$key} };

 などとしても参照できませんでした.

補足日時:2002/03/25 12:10
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QCなどで要素の数が固定できない配列はどうやって実現しますか?

配列について質問します。

BASIC系では配列は動的配列で要素の数が自由に変えられます。
ですが、C等では宣言時に配列の要素の数を決めておかねばならなかったと思います。
もし、C等で要素の数がわからないけど、配列を使いたい場合、どうすればいいのでしょうか?
どのように実現するのでしょうか?
配列と同じ使い勝手なら配列でなくともかまいません。

今はVBAでプログラムを組んでいるので、動的配列を使えばすむのですが、いずれ他の言語に移植したいので、できるだけ使わないようにしたいと思っています。

よろしくお願いいたします。

Aベストアンサー

malloc等のメモリ確保はNo.1さんの回答のリンクが詳しいですね。
C言語でプログラムを組む場合は、大抵はこれらメモリ操作関数のお世話になります。

これに加えて、C++やJavaのライブラリでは、動的配列クラスというものが使えます。
C++だとvectorやlist、JavaだとVectorやArrayListあたりですね。
他にも、言語や環境に依存したライブラリ、フレームワークで
様々な動的配列の機構が用意されていたりします。

簡単にまとめると、
・malloc、free、realloc等を使う方法 → ReDim
・動的配列クラス → Collection
のようなものだと考えてください。

QPerlのクラス(*.pm)からuseする側の*.cgi内ののスカラやハッシュ、配列の参照は可能でしょうか?

 Perlのクラス(*.pm)からuseする側の*.cgi内ののスカラやハッシュ、配列の参照は可能でしょうか?
いろいろなサーバに対応させやすくするため
1行目(Perlのパス)や各種モジュールのパスや設定情報を*.cgiに書いてプログラム本体は*pmに置きたいのです。
それとももっといい方法がございますでしょうか。
 教えて!ください。

Aベストアンサー

モジュールに渡したい変数をハッシュにしておいて、

モジュールのほうで、

sub new{
my $class = shift;
my %param = @_;
my $self = { param => \%param};

return bless($self,$class);
}

useする側では、

my $hoge = new hoge(%in);

とすると、$hoge->{param}でnewで渡したパラメータが読めます。
これを利用すれば大丈夫ではないでしょうか。

QC#かJavaで、配列の中から別の配列を探し出す

お世話になります。

C#かJava(CやC++は入れない)で、特定の配列の中に、該当する
配列があるかどうかを調べるメソッドがあれば、教えてください。

例えば…

int[] a={0,0,0,1,2,3,4,5,6,7};
int[] b={3,4,5};

ならば、『5』が返ってくるなどです。

力技では、aの配列を順にみていき、bの一番目と同じなら、
お互いの配列の次の要素を比較…などとやっていくのですが、
これらの方法を、標準のメソッドがあれば…と思い、
質問させていただきました。

以上、よろしくお願いいたします。

Aベストアンサー

Javaだけの話です。(以下、indexはbの添字)
int型配列aに含まれるint型配列bの要素の先頭の添字だけ欲しい場合
Arrays.binarySearch(a,b[index]);
int型配列aに含まれるint型配列bの要素の全添字欲しい場合
Arrays.binarySearch(a,from,to,b[index]);//from,toは配列aの走査対象要素

配列がオブジェクト型でもいいなら、Listを実装したクラス(ArrayListなど)に放り込みます。

オブジェクト型配列aに含まれるオブジェクト型配列bの要素があるか否か
listA.contains(b[index]);
オブジェクト型配列aに含まれるオブジェクト型配列bの要素の先頭の添字だけ欲しい場合
listA.indexOf(b[index]);
オブジェクト型配列aに含まれるオブジェクト型配列bの要素の最後の添字だけ欲しい場合
listA.lastIndexOf(b[index]);

最初に見つかる添字だけ欲しいなら標準ライブラリで取得できますが、
全添字が欲しいとなると途端に泥臭くなります。

Javaだけの話です。(以下、indexはbの添字)
int型配列aに含まれるint型配列bの要素の先頭の添字だけ欲しい場合
Arrays.binarySearch(a,b[index]);
int型配列aに含まれるint型配列bの要素の全添字欲しい場合
Arrays.binarySearch(a,from,to,b[index]);//from,toは配列aの走査対象要素

配列がオブジェクト型でもいいなら、Listを実装したクラス(ArrayListなど)に放り込みます。

オブジェクト型配列aに含まれるオブジェクト型配列bの要素があるか否か
listA.contains(b[index]);
オブジェクト型配列aに含まれるオ...続きを読む

Q配列とハッシュの配列の要素を比較してファイルに書き出したい

配列Aとハッシュの配列Bがあり、配列の内容をファイルに書き出そうとしています。このとき、パターンマッチをして、Aにしかない場合はAのデータを、Bにしかない場合はBを、両方にある場合は、Aをファイルに出力しようとしています。

以下のようなループのまわし方をしようとして、試行錯誤しましたが、うまい方法を思いつくことができませんでした。
ご教授いただければうれしいです。

while (defined $A[$i]) {
 my ($name, $pass);
 $j=0;
 while (($name, $pass) = each(%{$B[$j]})){
   if ($A[$i] =~ /$name/) {

   }
   $j++;
 }
$i++;
}

Aベストアンサー

いくつか不明な点があります。
・Bの要素は、キーと値のどっちを出力するのか。
・出力の順番はどういう風なのか。

とりあえず、比較部分として私が思いついたのは、

・Aにある要素をまず出力する。
・この時、Bにも要素があるのならBから要素を削除する。
・Bの残った要素を出力する。

という方法です。
ただし、配列Bの中身をいじくりたくないのであれば、いったん中身を(ハッシュリファレンスの中身も含めて)コピーする必要があります。
ですが、比較部分が一回で済むのでそれなりに効率は良いと思います。

QC言語の2次元配列 容量が大きすぎる場合の対処方法

私はC言語をもちいて2次元配列を作ろうとしています。

しかし、配列数が double c[10000][10000];
と大きいものにすると、エラーになってしまいます。

もちろん小さい double c[10][10];
のような配列では問題ありません。

malloc関数とかも調べたのですがなかなかいい文献が見つからずに
困っています。
どうかいいご意見があればよろしくお願いします。

Aベストアンサー

No.5です。
>今はa[],b[]に10000個の配列があります。これをc[a][b]に格納するためにどうするか、例文を書いていただいてもよろしいでしょうか?

例文ではありませんが、感じだけ書きましたので参考にしてください。
パラメタの順序や型は正しくないと思いますので、各関数はよく調べて使ってください。あくまで、こんな感じ、ということです。
-------------------
#include <stdio.h>
#include <io.h>

double read_c(FILE *fp, int x, int y) {
 double c;
 fseek(fp,(x*10000+y)*8L, SEEK_SET);
 fread(&c, 1,8, fp);
 return c;
}

void write_c(FILE *fp, double *c, int x, int y) {
 fseek(fp,(x*10000+y)*8L, SEEK_SET);
 fwrite(c, 1,8, fp);
}

int main(void)
{
 FILE *fp;
 double c,s;
 int x,y;
 int a[10000],b[10000];
 
 fp = fopen("c.dat","w+b");// double c[10000][10000]; の意味
 
 for(x=0; x<10000; x++) {
  for(y=0; y<10000; y++) {
   c=a[x]*b[y];
   write_c(fp, &c, x,y);// c[x][y]=a[x]*b[y]; の意味
  }
 }
 
 for(x=0; x<10000; x++) {
  s=0;
  for(y=0; y<10000; y++) {
   s += read_c(fp, x,y);// s += c[x][y]; の意味
  }
  b[x] = s / 10000;
 }
 
 fclose(fp);
 return 0;
}

No.5です。
>今はa[],b[]に10000個の配列があります。これをc[a][b]に格納するためにどうするか、例文を書いていただいてもよろしいでしょうか?

例文ではありませんが、感じだけ書きましたので参考にしてください。
パラメタの順序や型は正しくないと思いますので、各関数はよく調べて使ってください。あくまで、こんな感じ、ということです。
-------------------
#include <stdio.h>
#include <io.h>

double read_c(FILE *fp, int x, int y) {
 double c;
 fseek(fp,(x*10000+y)*8L, SEEK_SET);...続きを読む

Qハッシュの配列???

基本的なことなのですが、
@data{qw(aaa bbb ccc)}
と書くとどのようなデータ構造になるでしょうか?
要素に値を代入するにはどのように書けばいいでしょうか?

Aベストアンサー

この構文はスライスというものです。
my @tags = qw( id name comment ... );
my %data;
@data{ @tags } = readdata();
使うとすればこういったパターンになると思います。
用途と言えば「リスト値に一気に個別の名前をつける」といった感じです。

配列のスライスも($arr[0],$arr[1],$arr[2])が
@arr[0,1,2]となるように「$が@になってるだけ」ですね。
Perl5では変数の先頭の記号がデータの形式を表すと理解すれば混乱は無くなるでしょう。

Qc言語の配列の先頭アドレスが偶数アドレスとなる理由について

c言語の配列の先頭アドレスが偶数アドレスとなる理由について

下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。

/*list0105*/
#include <stdio.h>
main()
{

char na=1;
char nb=1;
char c[2] ={1,2};
char s[3] = {1,2,3};
char nc=1;
char nd=1;

printf("%p\n",&na);
printf("%p\n",&nb);
printf("%p %p \n", &c[0],&c[1] );
printf("%p %p %p \n", &s[0],&s[1] ,&s[2] );
printf("%p\n",&nc);
printf("%p\n",&nd);


}

実行結果
0xbffff8cf
0xbffff8ce
0xbffff8cc 0xbffff8cd ← c配列
0xbffff8b0 0xbffff8b1 0xbffff8b2 ← S配列
0xbffff8af
0xbffff8ae

c言語の配列の先頭アドレスが偶数アドレスとなる理由について

下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。

/*list0105*/
#include <stdio.h>
main()
{

char na=1;
char nb=1;
char c[2] ={1,2};
char s[3] = {1,2,3};
char nc=1;
char nd=1;

printf("%p\n",&na);
printf("%p\n",&nb);
printf("%p %p \n", &c[0],&c[1] );
printf("%p %p %p \n", &s[0],&s[1] ,&s[2] );
pr...続きを読む

Aベストアンサー

メモリの配置はコンパイラとコンパイルオプションに依存します。
デフォルトだと、32ビットのメモリ処理単位=4バイトとか8バイトが多いかと。
理由は32ビットCPUが4バイト単位でメモリにアクセスするのでアクセス効率を優先したためです。

例えば、
0xbffff8cc 0xbffff8cd ← c配列
0xbffff8ce 0xbffff8cf 0xbffff8d0 ← S配列
だとしたら、S配列の内容全てを参照するためにCPUは0xbffff8ccと0xbffff8d0の合計8バイトにアクセスする必要が出てきます。無駄ですよね。

Q文字実体参照が勝手に変換されてしまう

簡単な問合せフォームを作成中に文字実体参照に変換した文字が、元に戻されてしまい困っています。簡単なサンプルを作成してみましたが、以下の様な状態です。
1.入力フォームを持ったHTMLに
「<>と&lt;と&gt;」
と入力し、xxx.cgiに渡します。
2.xxx.cgi内で入力文字列を取得し、文字実体参照に変換後<hidden>で値を保持、再度xxx.cgiに<hidden>の文字列を渡すようにします。この時点で入力値は
「&lt;&gt;と&amp;lt;と&amp;gt;」
となります。
3.再度xxx.cgiが呼ばれると、文字実体参照に変換する処理が行われる為、入力値が
「&amp;lt;&amp;gt;と&amp;amp;lt;と&amp;amp;gt;」
となるはずですが、
「&lt;&gt;と&amp;lt;と&amp;gt;」
となってしまいます(変換処理が行われているはずなのに変換されていない)不思議に思って変換前のCGIの引数を確認してみると、
「<>と&lt;と&gt;」
と文字実体参照が元に戻されてしまっています。
ちなみに文字実体参照の変換処理は$valueに対象の文字が入っているとして以下の方法で変換しています。
----------
$value =~ s/&/&amp;/g;
$value =~ s/"/&quot;/g;
$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;
$value =~ s/\n/<BR>/g;
----------
こういった現象についてでも何か分かるようでしたら宜しくお願いします。

簡単な問合せフォームを作成中に文字実体参照に変換した文字が、元に戻されてしまい困っています。簡単なサンプルを作成してみましたが、以下の様な状態です。
1.入力フォームを持ったHTMLに
「<>と&lt;と&gt;」
と入力し、xxx.cgiに渡します。
2.xxx.cgi内で入力文字列を取得し、文字実体参照に変換後<hidden>で値を保持、再度xxx.cgiに<hidden>の文字列を渡すようにします。この時点で入力値は
「&lt;&gt;と&amp;lt;と&amp;gt;」
となります。
3.再度xxx.cgiが呼ばれると、文字実体参照に変換する処理が...続きを読む

Aベストアンサー

どうやら&lt;などをHiddenで渡しても渡すときに元の<にもどってしまうようです。
(HIddenではなくtextとして表示させて送るのと同じ。見えているか見えていないかの違い)

↑経験則なので仕様なのかどうかは知りません。

QC言語でunsigned char配列を連結する方法ってありますか?

C言語でunsigned char配列を連結する方法ってありますか?

例えば
unsigned char test[]={0x00,0x02,0x03};
unsigned char test2[]={0x05,0x06};
という配列があったとして

test[]という配列のあとにtest2の配列を追加することは可能でしょうか?
{0x00,0x02,0x03,0x05,0x06}という配列になればOKです。

よろしくお願いします。

Aベストアンサー

testの領域は3バイトのため、それ以上の配列を追加することは出来ません。
もし、testのサイズが5バイト以上あれば、test2を追加することは、できます。
その場合は、memcpy(&test[3],test2,2); とすれば、
testの4バイト目からあとに、test2の2バイトが追加されます。
新たに配列を作成して良いなら、
unsigned char test3[5];として
memcpy(test3,test,3);
memcpy(&test3[3],test2,2);
とすれば、test3はtestとtest2を連結したものとなります。

QPerlでハッシュや配列で重複するキーについて

ハッシュで重複するキーが値となるので、このハッシュはabdの3つのキーしか存在しないということでしょうか?
%a = ('a'=>1, 'b'=>2, 'a'=>3, 'd'=>4);

また、配列の場合はabadと4つ数になるということでしょうか?
@a = ('a','b','a','d');

この場合配列で、重複する値を抽出するアルゴリズムが知りたいです。

Aベストアンサー

重複のチェックはこんな感じでいいでしょう。

@a = ('a', 'b', 'a', 'd');

for (@a) {
  if (defined $hash{$_}) {
    print $_, "が重複してます。\n";
    next;
  }
  $hash{$_} = 1;
}


人気Q&Aランキング

おすすめ情報