『L・DK』上白石萌音&杉野遥亮インタビュー!

メールヘッダーの解析をリファレンスを使っているが、上手く出来な
い。理由は、無名配列を使っていない為に常に最後のデータでで上書き
される為。ここで、無名配列を使った方法が良く分からない。

メールヘッダーの構造は下記の通り。
① 最初にヘッダー、次がデータの順で構成されている。
② ヘッダーの開始は、Return-Path:から始まる。
③ ヘッダーの終わりは、空行。/^$/
④ データの開始は、ヘッダーの終わりの空行の次の行から開始する。
⑤ データの終わりは先頭のピリオドのみのデータ /^\.$/

上記の構成で、ヘッダーを配列@headerにデータを@dataに入れる。
ここでは、常に最初は@headerに次は@dataに交互に格納される。

@headerと@dataには、複数行のデータを配列のリファレンスとして格納
する。今の状況は夫々@headerと@dataには確かにリファレンスは格納さ
れているが。無名配列を使っていない為に、常に最後のデータしか格納
されていない。

ここでは、@headerの要素の@header_lineと@dataの要素の@data_lineへ
のデータの格納が不味い。ここの所をどの様にして無名配列を使ったら
良いのか、指摘をお願いします。

宜しく回答願います。

なお、今の不具合が発生をしているperlのソースを掲載します。これは
無名配列を使っていません。そこから、上記のバグが発生をしていま
す。

このソースを無名配列を使ったやり方に変更をしたい。宜しく回答願い
ます。また、これに関しては一番簡単な方法と言うのは、use strrict
宣言をしてから、夫々の@header_lineと@data_lineにmyの宣言をすれば
良いとは分かっていますが。

それ以外の方法での解決をお願いします。この手の問題と言うのは、私
は余りリファレンスを使う事が無いので。これを機会にして一つの定石
にしたいと思っていますので。宜しくお願いします。

長々と長い質問になりましたが宜しくお願いします。

下記の問題のperlのソースを掲載します。宜しくお願いします。

@header=();
@data=();
while(<>){
if(/^Return-Path:/){
$flag="header";
@header_line=();
$tmp=join("->",$.,$_);
push @header_line,$tmp;
next;
}

if($flag eq "header"){
if(/^$/){
$tmp=join("->",$.,"<blank>\n") ;
push @header_line,$tmp;
push @header,\@header_line;
$flag="data";
@data_line=();
next;
}
}

if($flag eq "data"){
unless(/^\./){
$tmp=join("->",$.,$_);
push @data_line,$tmp;
next;
}else{
$tmp=join("->",$.,$_);
push @data_line,$tmp;
push @data,\@data_line;
next;
}
}
}

for $i(0 .. 2434){
@ref_header=@{$header[$i]};
print @ref_header;
@ref_data=@{$data[$i]};
print @ref_data;
}

質問者からの補足コメント

  • うーん・・・

    いつも、回答をして頂き有難う御座います。

    回答は、唐突に質問者が使っていないコードでは無くて
    質問者の使っている言葉での説明をお願いします。

    唐突な言葉と言うのは、質問者の理解には何の役にも
    立ちません。質問者の視線に合わせての回答を願います。

    そうしないと折角の努力が実りません。大穴の空いたバケツ
    に水を注ぐ様な物です。私が逆の立場で回答をする立場で
    回答をする場合は、質問者が使っている言葉で説明をする
    様、努めますが。

    今後とも宜しくお願いします。
    言葉だけで理解をさせ様とする所なので中々難しい所で
    は有ります。

      補足日時:2017/03/09 20:55
  • うーん・・・

    二つ目は、@headerの要素には無名配列の要素が入っている。この時の
    リファレンスは毎回に異なる値が入っている。然し、毎回異なる値のリ
    ファレンスが入っていたとしても、無名配列の中の要素その物はつねに
    同じ値が入っているのだから。結果として最初のpush
    @header,\@header_lineとやっている事は同じではないのかと。

    と言う事を私は何回も記憶領域と言う言葉を使って切実に訴えての質問
    をしていると思いますが。何故に分かろうとしてもらえないのか。ここ
    にも当然に、それなりの理解の違いが横たわってはいますが。
    ...続く。

    No.3の回答に寄せられた補足コメントです。 補足日時:2017/03/10 07:24
  • うーん・・・

    それは分かりますが。私が言いたかった言葉と言うのは。分かってもら
    えたでしょうか。私が立場を代えて、この質問者の立場から一転して回
    答者の立場になったならば。ここは、必らず質問者の言葉を使って説明
    をしないと質問者は立腹をすると言う事は目に見えると思いますが。

    私は前回にも言ったんですが。この世の大半は知らない人の世界で動い
    ている。だって全てを知っている人はいないわけですから。その一部で
    しか持ち合わせてはいないですから。だから、唐突にお酒の成分の話を
    した時に「蛋白質」の話がどうのこうのと言っても、トナーの導電性と
    かの話をされても知らない人は知らない。知っている人は、息を吐く様
    に知っている。

    そこから、質問者もこれくらいは知っていると言う事での安易な回答は
    それこそ誤解と曲解に油に火をを注ぐ事になる。
    ...続く。

      補足日時:2017/03/10 07:30
  • うーん・・・

    長くなりましたが。気を悪くされたらごめんなさい。往々にしてこの様
    な事は有り得ると思います。当然にこの様な事は黙って言わない万が大
    半だとは思いますが。

    私は言います。だって、改善をしないのですから。私は、現実世界の中
    でもかなりにこの様な事はします。今後の回答に役立ててほしいからで
    す。

    宜しく、この趣旨を理解をされての回答をお願いします。
    ...終わり

      補足日時:2017/03/10 07:31

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

A 回答 (4件)

$r = [] ;



{my @ary = () ; $r=\@ary ;}
と(ほぼ)同じです。

$r = [1,2,3] ;

{my @ary = (1,2,3) ; $r=\@ary ;}
と同じです。

と、考えれば
$r = [ @list ] ;

{my @ary = (@list) ; $r=\@ary ;}
と同じ、ということになります。

このときの、 @ary と @list の関係がどうなっているか、よく考えてみましょう。
print \@ary , \@list ;
とかやってみてもいいでしょう

http://perldoc.jp/docs/perl/5.14.1/perldata.pod# …
が参考になります。


> use strrict 宣言をしてから、夫々の@header_lineと@data_lineにmyの宣言

use strrict と my は直接関係はありません。

http://perldoc.jp/func/my
myは「ローカル変数」を定義するためのものです。
use strict とは関係無く利用できます。

http://perldoc.jp/docs/perl/5.12.3/strict.pod
use strict あるいは use strict "vars"; は、未定義の変数を使えないようにするもので、
結果 my を使うことが多くなりますが、他の手段の方が好ましいこともあります(our とか)


「よいプログラム」の作り方として
・グローバル変数は使わない
・ローカル変数も、できるだけ有効範囲を狭くする
というのがあります。

Perlでも
・そのままではグローバルになるので、my を着ける
・my を忘れないようにuse strict を使う
というのが、昨今の流れです。
    • good
    • 0
この回答へのお礼

有難う御座います。

いつも思うのですが。コンテキストが何かずれている感じがします。
情報のアウトラインと言う言葉をご存知でしょうか。

ハイコンテキストモデル、ローコンテキストモデルが有りますよね。
人に言うのは簡単ですが。いざやるとなると、中々難しいですね。
人に説明をすると言うのは当人が理解をするのとは違う世界です。

名選手、必らずしも名監督ならずです。
野球の王選手と長嶋監督がその端的な現れですが。

コードでの回答は、コードに有らず。
説明での回答は、ここぞとばかりのコードに指す。
一番説明をして欲しい所は、ここぞとばかりにぼかす。

この場合の私の質問の趣旨を理解をしての回答なのでしょうか。
回答を貰って置きながら小言を言いまして済みません。

人に分かる様に説明をする為には、良く聞いて要点の整理が必要です。
私は、一体何を質問をしたのでしょうか。

有難う御座いました。

お礼日時:2017/03/09 20:41

Return-Path の処理で、@header と @data に無名配列を追加すれば、@header_line と @data_line は必要ないと思います。

以下は Return-Path 行の処理の一例です。残りの header と data も少しコードを修正すれば、直接無名配列に格納することができます。

if(/^Return-Path:/){
$flag="header";
push @header, [];
push @data, [];
$tmp=join("->",$.,$_);
push @{$header[-1]},$tmp;
next;
}
    • good
    • 0
この回答へのお礼

有難う御座います。

/^return-Path:/でヘッダーが始まる。それを、$flag="header"として
記録する。ここ迄は分かります。然し、次のpush @header,[]と言うの
が分かりません。この時の@headerには何が入るのでしょうか。

また、おなじ事ですが。push @data,[]と言うのが分かりません。と言
うのは、今のじょうたいと言うのはヘッダーなので@dataとは関係は無
いと思うのですが。

また、この時のpush @data,[]と言うのも@dataには何が入るのか分かり
ません。

回答の中で、一番分からないのが。最後のpush @{$header[-1]},$tmpで
す。$tmpの内容は分かります。然し、@{$hrader[-1]}と言うのが何なの
か。分かりません。

すみません。分からない事ばかりですが。私の理解はそんな物です。す
みません。教えて下さい。多分に、その辺が今回の問題の肝の様な感じ
がします。

宜しくお願いします。

お礼日時:2017/03/10 18:02

@foo = @bar;


でも
$foo = [@bar];
でも, @bar の全ての要素が改めてコピーされる (と思っていい).

で「質問者の使っている言葉での説明」ということだが, ではまずあなたが
push @header,\@header_line;

push @header,[@header_line];
のそれぞれの動作をどのように理解しているのか, 適切なマニュアル等を引用しながら説明してくれないかな. 「質問者の使っている言葉での説明」を求めるということは, 逆にいえば「質問者の使っている言葉」について問われれば委細漏らさず「これでもか」というくらい厳密に説明してくれるってことだよな?
この回答への補足あり
    • good
    • 0
この回答へのお礼

有難う御座います。

私が前回の時に使った言葉の中で繰り返し使っている言葉と言うのが有
りますよね。その言葉で説明をして欲しかったのですが。それは、必ら
ずしも多分に回答をされて全くごく当り前に理解をされている方に取っ
てはりふぜんかも知れませんが。然し、ここではその言葉を使って説明
をしてほしかった物ですから。

私は、繰り返し何回も同じ言葉を使って質問をしています。また、その
言葉を使って回答をしてもらわないと私は納得し難いです。

それは、記憶領域と言う事です。私は何回もそこでは繰り返し
push @header,\@header_line;

push @header,[@header_line];
を使っていますよね。

だから、当然にこの言葉を使っての説明を求めている訳です。何故に唐
突にこの言葉以外での説明をするのでしょうか。私は、何回もその言葉
で切実に訴えての質問をしていますよね。何故、理解をしようとしない
のでしょうか。

一般的な話題でも確かに言おうとしている事は分かリますよ。然し、
もっと的確に手短に相手に伝えるにはそれが直球で伝わると思うのです
が。

回答者と質問者の間には、相当の溝が有ると言う事を先ずは理解をして
ほしいと思います。質問者は回答者と全く違うスキルの壁が有ります。

私が前に質問をした内容を一言で言うと。
push @header,\@header_line;

push @header,[@header_line];
の違いは何ですかと言う事ですが。

それを記憶領域と言う言葉を使って説明を求めていると言う事がどうし
て分かってもらえないのだろうか。

だって、当然にその様なネットでの情報を得てもこの様に理解をしてな
いのですから。かなりに誤解と曲解をしているのですから。必りにスキ
ルに難癖が有るのですよ。

また、蒸し返す様で質問をしますが。push @header,\@header_lineは、
@headerの要素には@header_lineのリファレンスが入っている。
...続く

お礼日時:2017/03/10 07:20

一番簡単なのは


push @header,\@header_line;

push @data,\@data_line;
をそれぞれ
push @header,[@header_line];

push @data,[@data_line];
に変えること.
    • good
    • 0
この回答へのお礼

有難う御座います。

push @header,\@header_lineとpush @header,[@header_line]の違いが
今一つ分かりません。@header_lineと言うのは、同じ変数を使いまわし
ているので最初の記憶領域は同じなので私の今の処理は常に上書きされるの
が原因で、最終結果は最後の処理の内容が格納されます。

これは、push @header,[@header_line]にしても@header_lineその物は
同じ記憶領域を使っているのでpush @header,\@header_lineと同様の現
象になると思っていたのですが。

私のどの部分に理解が足りないのでしょうか。私が思うには例えこの場
合は無名配列にしても中身の@header_lineその物は常に同じ値を示して
いるので意味が無い様に思うのですが。

実際は、そうでは無くてきちんと夫々違う記憶領域を確保しています。
私は無名配列は単にその都度違う記憶領域を確保するだけで有ってその
要素に付いては別物だと思っていたのですが。

その中身についても違う記憶領域を確保すると言う事でしょうか。済み
ません。もうこのコードが動くと言う事は出来たので。今度は中味に付
いて説明をお願いします。

宜しくお願いします。

お礼日時:2017/03/09 09:47

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

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

QC言語の漢字のホルダーは、chdirでは変更出来ないのだろうか。

下記のソースでは、ホルダーが漢字で無い時は成功するが。
漢字を使うと失敗する。

下記に成功する場合を示す。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(){
char *dir1="C:/Users/usui/mingw";
int ret;

ret=chdir(dir1);
printf("%d\n",ret);
}
上記は、漢字を使っていないので結果は0を表示する。
然し、ホルダーに漢字を使うと-1を表示する。

漢字のホルダーを使う方法をお知えて下さい。
宜しくお願いします。

Aベストアンサー

No3です。
ちなみに私がインストールした(今使っているバージョン)のは、下記URLの
mingw-get-inst-20120426.exe です。
https://sourceforge.net/projects/mingw/files/OldFiles/mingw-get-inst/mingw-get-inst-20120426/

QC言語でのUTF-8の文字列の処理は例えば、比較とかstrtokとかはどうするのか

大量のhtmlファイルを処理をする様になってから今迄はperlを使って来
たが処理が遅いのでC言語を使って早くしようと思って要るが。肝心の
日本語コードの扱いで詰まっている。

例えば、
<!--コメントヘッダーのはじまり-->
.
.
.
<!--コメントヘッダーのおわり-->
と言った場合に、<と>に囲まれた色んなタグが現れて来る。strtokで文
字列を拾って対処をするとしても、文字コードが処理出来なければ何も
進まない。

例えば、上記の場合でhtmlファイルを読んでコメントヘッダーのはじまり
とおわり迄に関しては、出力をしない。他のは全て出力すると言う様な場
合のC言語のソースはどの様に成るのでしょうか。

済みません。未だ、始めたばかりでC言語での記述が出来ません。宜し
く回答願います。

回答はヒントでは無くて直接のC言語のソースを提示願います。宜しく
お願いします。

Aベストアンサー

>回答はヒントでは無くて直接のC言語のソースを提示願います。

これがほしければ、もうちょっと具体的な入出力についての説明が必要です。

ヒントレベルになりますが、状態変数を使って、
状態1:コメント外・・・strstr()などを使って"<!--"を探し、そこまでを出力→状態2へ
状態2:コメント内・・・strstr()などを使って"-->"を探し、その一つ右へポインタを進める→状態1へ
これをHTMLの最後まで繰り返します。

ファイルの中身をすべていったんメモリに持つなら'\0'を見つけるまで繰り返すだけです。限られたバッファでやりくりしようとするなら(ネットワークからダウンロードしながら処理する際にはこのやり方が必須)、バッファ読み込みの際のタグ文字列の泣き別れなどを考慮する必要がありちょっと凝ったテクニックが必要になります。

それとも、UTF-8で書かれたHTMLの"<!--コメントヘッダーのはじまり-->"~"<!--コメントヘッダーのおわり-->"を全削除ですか?だったら、コードをUTF-8で書いて、strstr()で"<!--コメントヘッダーのはじまり-->”を見つけて・・・でいけると思います。文字コードの処理というよりか、見る人が見れば日本語に見えるかもしれない「ただのデータの列」とみなして処理するだけです。

>回答はヒントでは無くて直接のC言語のソースを提示願います。

これがほしければ、もうちょっと具体的な入出力についての説明が必要です。

ヒントレベルになりますが、状態変数を使って、
状態1:コメント外・・・strstr()などを使って"<!--"を探し、そこまでを出力→状態2へ
状態2:コメント内・・・strstr()などを使って"-->"を探し、その一つ右へポインタを進める→状態1へ
これをHTMLの最後まで繰り返します。

ファイルの中身をすべていったんメモリに持つなら'\0'を見つけるまで繰り返すだけです。限られた...続きを読む

QCのプログラムに無性にイライラするのはおかしいですか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  hn[ p[0] ]++;
 }
}

3重にするならせめて、y,x,i の順にしてp[0]への代入は1回で済ませればと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  for( i=0; i<256; i++){
     if(p[0]==i){hn[i]++;}
  }
 }
}

最近のコンパイラの最適化では、私の書いたようなコーディング(修正?)は無意味なのでしょうか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++)...続きを読む

Aベストアンサー

利点を考えてみました


これを並列処理したときに
スレッド0: hn[0] に p[0] = 0 をカウント
スレッド1: hn[1] に p[0] = 1 をカウント
...
とすれば、
・img -> imageData は読み出すだけなので衝突しない
・hn[i] でアクセスする領域は、スレッド毎に i が違うので、同じ箇所に書き込まれることはない。
となり、排他処理が不要となります。
(もちろん、x,y,i,p[0]はスレッドでローカルな変数とします)

ただ、並列処理のオーバーヘッドや同時並列処理数等を考えると、こんな並列処理はしない方が効率的です。


あるいは、hn[]がシークに時間がかかる領域の場合、
hn[p[0]) で毎回違う位置を探しに行って、その時間が無視できないほどだったら、
先にhnを決めてしまった方が速くなるでしょう。

こちらも、非現実的です。

QC言語のうるう年に関するプログラムの作成

C言語(閏年)の質問です。

任意の範囲の年から閏年の表示とその数をカウントして次の実行結果のように表示するプログラムの作成方法を教えてください。(ここでは2つの年をmain関数内で入力し、その範囲の西暦を引数とする関数checkYearを使用するものとする。int型の関数checkYearは、引数に西暦をとり、その西暦が閏年であれば、1を返し、閏年でない場合は0を返す。)
なお、閏年の判定方法は以下のとおりである。
条件1 西暦年が4で割り切れる年は閏年である
条件2 条件1を満たしていても、西暦年が100で割り切れるときは閏年でない
条件3 条件2を満たしていても、西暦年が400で割り切れるならば閏年である

実行例1
西暦を入力:2000
西暦を入力:2009
2000年
2004年
2008年
閏年は3回あります。

実行例2
西暦を入力:2100
西暦を入力:2000
2000年
2004年
2008年
2012年
2016年
2020年
(省略)
2096年
閏年は25回あります。

実行例3
西暦を入力:2090
西暦を入力:2110
2092年
2096年
2104年
2108年
閏年は4回あります。

C言語(閏年)の質問です。

任意の範囲の年から閏年の表示とその数をカウントして次の実行結果のように表示するプログラムの作成方法を教えてください。(ここでは2つの年をmain関数内で入力し、その範囲の西暦を引数とする関数checkYearを使用するものとする。int型の関数checkYearは、引数に西暦をとり、その西暦が閏年であれば、1を返し、閏年でない場合は0を返す。)
なお、閏年の判定方法は以下のとおりである。
条件1 西暦年が4で割り切れる年は閏年である
条件2 条件1を満たしていても、西暦年が10...続きを読む

Aベストアンサー

こんな感じでしょうか。
(体裁上、各行先頭のスペースは全角スペースにしてあるので、コピペするとコンパイルできないと思います)

#include <stdio.h>

static int
checkYear (int year)
{
 if ((year % 4) == 0)
 {
  if ((year % 100) == 0)
  {
   if ((year % 400) == 0)
    return (1);
  }
  else
   return (1);
 }

 return (0);
}

int
main (int argc, char * argv[])
{
 int count = 0;
 int year, start, end;

 printf ("西暦を入力:");
 scanf ("%d", &start);
 printf ("西暦を入力:");
 scanf ("%d", &end);

 if (start > end)
 {
  year = end;
  end = start;
  start = year;
 }

 for (year = start; year <= end; year++)
 {
  if (checkYear (year) == 1)
  {
   printf ("%d年\n", year);
   count++;
  }
 }
 if (count != 0)
  printf ("閏年は%d回あります。\n", count);
 else
  printf ("閏年はありません。\n");

 return;
}

こんな感じでしょうか。
(体裁上、各行先頭のスペースは全角スペースにしてあるので、コピペするとコンパイルできないと思います)

#include <stdio.h>

static int
checkYear (int year)
{
 if ((year % 4) == 0)
 {
  if ((year % 100) == 0)
  {
   if ((year % 400) == 0)
    return (1);
  }
  else
   return (1);
 }

 return (0);
}

int
main (int argc, char * argv[])
{
 int count = 0;
 int year, start, end;

 printf ("西暦を入力:");
 scanf ("%d", &start);
 print...続きを読む

Qmakeで文字化けする。migwのmakeを使っています。

makeで文字化けをする。
mingwのmakeを使っています。

makeの設定の問題でしょうか。
環境はWindows7です。

宜しく回答願います。

Aベストアンサー

https://ja.wikipedia.org/wiki/Gettext
makeが各言語で表示されるしくみは、これ。

うろ覚えですが、MinGWでは、jaに対応している make.mo は、 ja_JP.EUC 用しかなかったように思います。
端末がSJISでは文字化けします。
たしか、他のコマンドも .moはEUC用だったはずです。

対策は次の通りです。
○ 日本語表示を止める
 ・LANG=C 等、日本語表示しない設定にする
 ・LANG=ja_JP.SJIS 等、コードも含めて設定する→SJISにすれば、EUCは使われない
 ・locale/ja/LC_MESSAGES/make.mo を削除する
○EUC使用で統一する
 ・chcpコマンドでコマンドプロンプトのコードをEUCに変える(他にどんな影響が出るか不明)
 ・cmd.exeではなく、(MinGW/MSYSの) bashを使う
○ja_JP.SJIS用 make.mo を作る
 ・ locale/ja/LC_MESSAGES/make.mo と差し替える
 ・ locale/ja_JP.SJIS/LC_MESSAGES/make.mo に置く

影響が少ないのは、環境変数LANGを変更することでしょう。

https://ja.wikipedia.org/wiki/Gettext
makeが各言語で表示されるしくみは、これ。

うろ覚えですが、MinGWでは、jaに対応している make.mo は、 ja_JP.EUC 用しかなかったように思います。
端末がSJISでは文字化けします。
たしか、他のコマンドも .moはEUC用だったはずです。

対策は次の通りです。
○ 日本語表示を止める
 ・LANG=C 等、日本語表示しない設定にする
 ・LANG=ja_JP.SJIS 等、コードも含めて設定する→SJISにすれば、EUCは使われない
 ・locale/ja/LC_MESSAGES/make.mo を削除する
○EUC使用で...続きを読む

QPerl テキスト処理について

いつもお世話になっております。

ご教示お願い致します。

画像のようなテキストファイルがあります(log.txt)
(画像の上2行は無視してください)

そこで、
まず、1列目が「1」の行合計 結果→2
1列目が「1」の行番号 結果→1と4(正確には0と3?)

というふうなことをしたいのですが、どのようにすればいいのでしょうか?

my $FILE = 'log.txt';
open(FILE, "<$FILE") or die("error :$!");
eval{ flock(FILE, 1) };
my @DATA = <FILE>;
$a = 0;
my @match = grep(/^1,/, @DATA);
while (<@match>) {
$a++;
}

「1,」から始めるものを抽出まではできたのですが・・・この先がわからないです;;

Aベストアンサー

以下の用にしてください。
----------------------------------
print qq(<br><center><div class="heading">カテゴリ</div></center>);
open(FILE, "<$FILE") or die("error :$!");
eval{ flock(FILE, 1) };
my @DATA = <FILE>;
$a = 0;
my @lineNo = ();
my $lno = 0;
foreach(@DATA){
if (/^1,/){
$a++;
push(@lineNo,$lno);
}
$lno++;
}
foreach(@lineNo){
printf qq(<center><div class="category"><a href="$_" style="text-decoration:none;">カテゴリ1 [ $x ]</a></div></center>), ++$mon, $date, $hour, $min;
}
---------------------------
1,4ではなく0,3が望みの数値なので、
$lno++;の位置を変えました。
<a href="ここの部分" は
<a href="$_"
としてください。

以下の用にしてください。
----------------------------------
print qq(<br><center><div class="heading">カテゴリ</div></center>);
open(FILE, "<$FILE") or die("error :$!");
eval{ flock(FILE, 1) };
my @DATA = <FILE>;
$a = 0;
my @lineNo = ();
my $lno = 0;
foreach(@DATA){
if (/^1,/){
$a++;
push(@lineNo,$lno);
}
$lno++;
}
foreach(@lineNo){
printf qq(<center><div class="category"><a href="$_" style="text-decoration:none;">カテゴリ1 [ $x ]</a></div></center>), ++$mon, $date, $hour,...続きを読む

Qc言語のプログラミングの問題で50以下の正の偶数を降順(大きい順)で表示するプログラムを作成できる方

c言語のプログラミングの問題で50以下の正の偶数を降順(大きい順)で表示するプログラムを作成できる方お願いします

Aベストアンサー

No3の方から既に回答がでていますが、別解です。
#include <stdio.h>

int main()
{
printf("50\n");
printf("48\n");
printf("46\n");
printf("44\n");
printf("42\n");
printf("40\n");
printf("38\n");
printf("36\n");
printf("34\n");
printf("32\n");
printf("30\n");
printf("28\n");
printf("26\n");
printf("24\n");
printf("22\n");
printf("20\n");
printf("18\n");
printf("16\n");
printf("14\n");
printf("12\n");
printf("10\n");
printf("8\n");
printf("6\n");
printf("4\n");
printf("2\n");
return 0;
}

以下、実行結果です。
------------------------------------
50
48
46
44
42
40
38
36
34
32
30
28
26
24
22
20
18
16
14
12
10
8
6
4
2

No3の方から既に回答がでていますが、別解です。
#include <stdio.h>

int main()
{
printf("50\n");
printf("48\n");
printf("46\n");
printf("44\n");
printf("42\n");
printf("40\n");
printf("38\n");
printf("36\n");
printf("34\n");
printf("32\n");
printf("30\n");
printf("28\n");
printf("26\n");
printf("24\n");
printf("22\n");
printf("20\n");
printf("18\n");
printf("16\n");
printf("14\n");
printf("12\n");
printf("10\n");
printf("8\n");
printf("6\n");
printf("...続きを読む

Qプログラムの改良

人の作ったプログラムを改良することになりました。
Visual C++ は初めてですが、CやC++は一通り勉強しています。

そこで、いろいろ調べているのですが、
例えば
「MFCは使わずに,Win32API SDKを用いた方法」
などという説明があります。

自分が対応しているプログラムが、そのどちらであるか、あるいはほかの方法で作られているか
というのはどうしたら分かるのでしょうか?

Aベストアンサー

No1です
私はC++は全然触ったこと無いので
あまり的確な回答は期待しないでくださいね

Q1.いいんじゃないでしょうか?
MSDNのOnPoint↓
https://msdn.microsoft.com/ja-jp/library/01c9aaty.aspx

OnPointクラス(Cwndクラス)
https://msdn.microsoft.com/ja-jp/library/1xb05f0h.aspx
このページの一番最初に
「Microsoft Foundation Class ライブラリにあるすべてのウィンドウ クラスの基本機能が用意されています。」と書いてありますから
そういうことですね

Q2.なんでもいいと思いますけど
そもそもあなたが対応するプログラムが
きちんとWin32のみで、もしくはMFCのみで書かれているとは限らないですからね
適当に作られて、両方が混在している可能性だってありますし

Q3.そこからですか
そこは調べればすぐ出てくるかと思いますが
MFCというのはWin32をラッピングしたものです

Q4.作った本人に聞く
仕様書とかがあるならそれを見る

No1です
私はC++は全然触ったこと無いので
あまり的確な回答は期待しないでくださいね

Q1.いいんじゃないでしょうか?
MSDNのOnPoint↓
https://msdn.microsoft.com/ja-jp/library/01c9aaty.aspx

OnPointクラス(Cwndクラス)
https://msdn.microsoft.com/ja-jp/library/1xb05f0h.aspx
このページの一番最初に
「Microsoft Foundation Class ライブラリにあるすべてのウィンドウ クラスの基本機能が用意されています。」と書いてありますから
そういうことですね

Q2.なんでもいいと思いますけど
そもそもあなたが...続きを読む

QC言語で詰まっているので教えて下さい。

下記のソースが有ります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
FILE *fp, *fp2;
char buf[64000];
char *p, *start ,*q ,*r;
char file_name[]="out/";
int ret;

// result.txtのopen error処理 {{{
fp=fopen("result.txt","r");
if(fp == NULL){
printf("result.txt file open err\n");
return 1;
}
// }}}
// fgetsでのエラー処理 {{{
if(fgets(buf,64000,fp) == NULL){
printf("data error\n");
return 1;
}
// }}}
// <target>が存在しない時のエラー処理 {{{
p=strstr(buf,"<target>");
if(p == NULL){
printf("target not found\n");
exit(1);
}
// }}}

// 最初のファイル名の取得{{{
p=p+strlen("<target>");
q=p;

p=strstr(p,"</target>");
if(p == NULL){
printf("</target> not found\n");
exit(1);
}
*p='\0';
strcat(file_name,q);
// }}}

// 出力ファイルのopen処理 {{{
fp2=fopen(file_name,"w");
if(fp2 == NULL){
printf("%s file open err\n",file_name);
exit(1);
}
// }}}
while(fgets(buf,64000,fp) != NULL){
p=strstr(buf,"<target>");
if(p == NULL){
fprintf(fp2,"%s",buf);
}else{
// 2回目以降のファイル名の取得{{{
p=p+strlen("<target>");
q=p;

p=strstr(p,"</target>");
if(p == NULL){
printf("</target> not found\n");
exit(1);
}
*p='\0';
strcat(file_name,q);
// }}}
// 今使っているファイルを閉じて新しいファイルを開く。{{{
fclose(fp2);

fp2=fopen(file_name,"w");
if(fp2 == NULL){
printf("%s file open err\n",file_name);
exit(1);
} // }}}
}
}
fclose(fp);
fclose(fp2);
return 0;
}

// vim:set fdm=marker:

入力は、result.txtを読んでそれをフィルターする物です。result.txt
は先頭から順に下記の内容で入力されています。

① <target>ファイル名</target>
② 内容のデータ

上記の①から②を繰り返します。フィルターは①のファイル名で続く
データをそのファイルに出力します。フィルターの数は約1万件にな
る。

処理の内容は、最初の<target>の行を読んで出力ファイルをオープンし
ます。続くデータを<target>行が来る迄出力を続行します。

新しく<target>行が来るとこれ迄使っていた出力ファイルを閉じてまた
新規のファイルを出力としてオープンします。

この処理をresult.txtを最後迄読んだら終了となります。今の問題は、
この処理の中で最初の出力ファイルに出力をしている途中で異常終了し
ます。

何処が不味いのか。検討が付きません。どうか助けて下さい。宜しくお
願いします。

下記のソースが有ります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
FILE *fp, *fp2;
char buf[64000];
char *p, *start ,*q ,*r;
char file_name[]="out/";
int ret;

// result.txtのopen error処理 {{{
fp=fopen("result.txt","r");
if(fp == NULL){
printf("result.txt file open err\n");
return 1;
}
// }}}
// fgetsでのエラー処理 {{{
if(fgets(buf,64000,fp) == NULL){
printf("data error\n");
return 1;
}
// }}}
/...続きを読む

Aベストアンサー

以下のようにしてください。
修正した箇所と、追加した箇所に//変更、//追加のコメントを入れておきました。
-------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
FILE *fp, *fp2;
char buf[64000];
char *p, *start ,*q ,*r;
char file_name_base[]="out/"; //変更
char file_name[256]; //追加
int ret;

// result.txtのopen error処理 {{{
fp=fopen("result.txt","r");
if(fp == NULL){
printf("result.txt file open err\n");
return 1;
}
// }}}
// fgetsでのエラー処理 {{{
if(fgets(buf,64000,fp) == NULL){
printf("data error\n");
return 1;
}
// }}}
// <target>が存在しない時のエラー処理 {{{
p=strstr(buf,"<target>");
if(p == NULL){
printf("target not found\n");
exit(1);
}
// }}}

// 最初のファイル名の取得{{{
p=p+strlen("<target>");
q=p;

p=strstr(p,"</target>");
if(p == NULL){
printf("</target> not found\n");
exit(1);
}
*p='\0';
strcpy(file_name,file_name_base); //追加
strcat(file_name,q);
// }}}

// 出力ファイルのopen処理 {{{
fp2=fopen(file_name,"w");
if(fp2 == NULL){
printf("%s file open err\n",file_name);
exit(1);
}
// }}}
while(fgets(buf,64000,fp) != NULL){
p=strstr(buf,"<target>");
if(p == NULL){
fprintf(fp2,"%s",buf);
}else{
// 2回目以降のファイル名の取得{{{
p=p+strlen("<target>");
q=p;

p=strstr(p,"</target>");
if(p == NULL){
printf("</target> not found\n");
exit(1);
}
*p='\0';
strcpy(file_name,file_name_base); //追加
strcat(file_name,q);
// }}}
// 今使っているファイルを閉じて新しいファイルを開く。{{{
fclose(fp2);

fp2=fopen(file_name,"w");
if(fp2 == NULL){
printf("%s file open err\n",file_name);
exit(1);
} // }}}
}
}
fclose(fp);
fclose(fp2);
return 0;
}
----------------------------------------------------
誤りは2点です。
1)strcat(file_name,q);
file_nameは"out/"が格納できるサイズしか確保されません。
その為、これを実行すると、確保したサイズ以降の領域が破壊されます。
どこが、破壊されるかは、コンパイラの配置によってきまるので、わかりませんが、どこかが破壊されます。
2)2回目のstrcat(file_name,q);を実行すると
前に実行した残骸のあとから更に文字列が追加されます。

上記を解決するためには
char file_name_base[]="out/"; //変更
char file_name[256]; //追加
を確保し、
一旦、
①file_name_baseをfile_nameにコピーし、
②その後で、strcat(file_name,q);
を実行します。
①②は、必ずペアで実行します。
尚、file_nameは暫定的に256バイトにしましたが、もっとファイル名として大きな文字列が存在するなら
もっと大きくしてください。

以下のようにしてください。
修正した箇所と、追加した箇所に//変更、//追加のコメントを入れておきました。
-------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
FILE *fp, *fp2;
char buf[64000];
char *p, *start ,*q ,*r;
char file_name_base[]="out/"; //変更
char file_name[256]; //追加
int ret;

// result.txtのopen error処理 {{{
fp=fopen("result.txt","r");
if(fp == NULL){
printf("result.txt file open err\n...続きを読む

QC++で大量のエラーが出る

下記で、大量のエラーが出る。
//C:/Users/usui/perl/LWP/170220-Iterative_processing/html/01.cpp {{{
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>

using namespace std; // }}}

class filter{
private:
int ret;
DIR *dir;
struct dirent *dp;
char path[]=".";
int ret;
string name;
public:
// コンストラクター
filter(string s){
name = s;
const char* cstr = name.c_str();
ret=chdir(cstr);
if(ret!=0){
cout << "chdirに失敗\n" << name <<endl;
exit(1);
}
//ret=chdir(path);
if((dir=opendir(path))==NULL){
perror("opendir");
exit(-1);
}

for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
if(strlen(dp->d_name)>10){
printf("<target>%s</target>\n",dp->d_name);
read_file(dp->d_name);
}
}
};
int main(){
filter dekita("C:/Users/usui/perl/LWP/170220-Iterative_processing/html");
}

// vim:set ft=cpp fdm=marker:

エラーの内容は下記。

01.cpp:12:2: error: 'DIR' does not name a type
DIR *dir;
^
01.cpp:14:15: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
char path[]=".";
^
01.cpp:15:6: error: redeclaration of 'int filter::ret'
int ret;
^
01.cpp:11:6: note: previous declaration 'int filter::ret'
int ret;
^
01.cpp:42:2: error: expected '}' at end of input
}
^
01.cpp:14:15: error: initializer-string for array of chars is too long [-fpermissive]
char path[]=".";
^
01.cpp: In constructor 'filter::filter(std::string)':
01.cpp:19:19: error: array used as initializer
filter(string s){
^
01.cpp:28:6: error: 'dir' was not declared in this scope
if((dir=opendir(path))==NULL){
^
01.cpp:28:22: error: 'opendir' was not declared in this scope
if((dir=opendir(path))==NULL){
^
01.cpp:29:19: error: 'perror' was not declared in this scope
perror("opendir");
^
01.cpp:33:17: error: 'dir' was not declared in this scope
for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
^
01.cpp:33:20: error: 'readdir' was not declared in this scope
for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
^
01.cpp:34:15: error: invalid use of incomplete type 'struct dirent'
if(strlen(dp->d_name)>10){
^
01.cpp:13:9: error: forward declaration of 'struct dirent'
struct dirent *dp;
^
01.cpp:34:23: error: 'strlen' was not declared in this scope
if(strlen(dp->d_name)>10){
^
01.cpp:35:38: error: invalid use of incomplete type 'struct dirent'
printf("<target>%s</target>\n",dp->d_name);
^
01.cpp:13:9: error: forward declaration of 'struct dirent'
struct dirent *dp;
^
01.cpp:35:46: error: 'printf' was not declared in this scope
printf("<target>%s</target>\n",dp->d_name);
^
01.cpp:36:16: error: invalid use of incomplete type 'struct dirent'
read_file(dp->d_name);
^
01.cpp:13:9: error: forward declaration of 'struct dirent'
struct dirent *dp;
^
01.cpp:36:24: error: 'read_file' was not declared in this scope
read_file(dp->d_name);
^
01.cpp: At global scope:
01.cpp:42:2: error: expected unqualified-id at end of input
}
^
どうも、CとC++では、関数の名前とかが違う様だが。済みません。間違いの
指摘をお願いします。

下記で、大量のエラーが出る。
//C:/Users/usui/perl/LWP/170220-Iterative_processing/html/01.cpp {{{
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>

using namespace std; // }}}

class filter{
private:
int ret;
DIR *dir;
struct dirent *dp;
char path[]=".";
int ret;
string name;
public:
// コンストラクター
filter(string s){
name = s;
const char* cstr = name.c_str();
ret=chdir(cstr);
if(ret!=0){
cout...続きを読む

Aベストアンサー

基本的には、コンストラクタの中で、static でない変数を初期化することは禁止されています(最初のメッセージは、警告メッセージで、C++11 の新規格なら許されると言うことです)

あと、C++であてtも、char path[] という配列を初期化することはできません。

ということです。


人気Q&Aランキング

価格.com 格安SIM 料金比較