トップページ⇒tech
1001コメント330KB

【初心者歓迎】C/C++室 Ver.54【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2008/05/14(水) 01:00:02
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.53【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1208989385/l50
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
05075062008/06/01(日) 14:14:24
そういうイミではなかったか・・・失敬。
0508デフォルトの名無しさん2008/06/01(日) 14:16:08
>>505
>>506
ありがとうございます。GETコマンドについて調べてみます。
右クリックメニューは、レジストリキーいじってたんですね。
0509デフォルトの名無しさん2008/06/01(日) 14:21:49
お前らvalarrayって使ってる?
0510デフォルトの名無しさん2008/06/01(日) 14:34:52
>>503
NULLが(void *)0と定義されていれば暗黙の型変換ができると思うけど
そうじゃなければ型指定しないとだめとかじゃないっけか?
0511デフォルトの名無しさん2008/06/01(日) 14:36:32
NULLの定義は環境依存だしな・・・不親切な説明だが
0512デフォルトの名無しさん2008/06/01(日) 14:37:51
Blitz++使ってる。
05135032008/06/01(日) 14:48:45
>>510
>>511

なるほど。#define NULL (void*)0
しているところばかりじゃないということですね。
ありがとうございます。
0514デフォルトの名無しさん2008/06/01(日) 15:59:33
>>513
いや、C++では #define NULL 0 で、その場合もc = NULLでOKと思うよ。
c = (char*)NULL にする必要性あるのかな。詳しい人よろしく。
0515デフォルトの名無しさん2008/06/01(日) 16:01:43
voidの本にキャストしなければならないって書いてあるからだろ。
0516デフォルトの名無しさん2008/06/01(日) 16:01:54
もし、C++でNULLを(void*)0にしてるような規格違反の処理系があれば、
c = (char*)NULL; とせざるを得ない。
0517デフォルトの名無しさん2008/06/01(日) 16:02:44
>>513
昔は違ったかもしれないが、少なくともC89以降、0やNULLはどのポインタ型へも
暗黙の変換ができることになっている。

NULLを(void*)0と定義するのは、
誤ってポインタ以外に使おうとしたときにエラーにさせることが主目的。
規格に沿えば、単に0などという定義でも全く問題ない。
0518デフォルトの名無しさん2008/06/01(日) 16:05:41
>>503
ANSI Cが制定される前のCでは、キャストが必要な処理系があった。
その時代のコードならNULLやmallocの戻り値をキャストしてるコードはよくある。
05195132008/06/01(日) 16:06:14
確かCではNULLが0か(void*)0にしてたが、C++だと型変換が厳しくなり、
NULLを(void*)0にするとc=(char*)NULLと
書かないといけなくなるから0にしたという話だったと思う。

0はC/C++どちらでもキャストしないでいいはず。(int* p = 0とか大丈夫でしょ)

いずれにしてもc=(char*)NULLと書く必要はない気がする。
05205132008/06/01(日) 16:08:54
518読む前に投稿してしまった。518が答えですかね。
0521デフォルトの名無しさん2008/06/01(日) 16:20:05
>>520
そんな簡単に騙されるなよ・・・
0522デフォルトの名無しさん2008/06/01(日) 16:20:41
cがchar以外のポインタに変えられた場合にエラーになってくれると
助かる場合には意味があるかもなぁ。
0523デフォルトの名無しさん2008/06/01(日) 18:42:01
C++ での NULL の定義は処理系定義だよ。
0 とは限らなくて、処理系独自のキーワードで定義されていることもある。
C でも C99 で処理系定義になった。
0524デフォルトの名無しさん2008/06/01(日) 18:43:54
>>503
C でも void* から別のポインタ型への暗黙のキャストをしようとすると警告出すコンパイラもある。
そういうコンパイラを黙らせるには明示的にキャストをしないといけない。
そういうことなんじゃないの?
0525デフォルトの名無しさん2008/06/01(日) 20:45:22
>>519
ただし、可変長引数の末尾には、(char *)NULL と書いておきなさい、という説があるみたいです。
0526デフォルトの名無しさん2008/06/01(日) 20:47:11
>>525
末尾に限らず可変長引数の途中でヌルポインタを渡したいときはキャストが必要。

同様に、実引数から型を推測するような関数テンプレートにもヌルポインタを渡す
ためにはキャストなどの注意が必要。
0527デフォルトの名無しさん2008/06/01(日) 21:10:23
>>525
NULL終端文字列として扱えるからな。
0528デフォルトの名無しさん2008/06/01(日) 21:19:04
お前は何を言ってるんだ
0529デフォルトの名無しさん2008/06/01(日) 21:26:04
>>527
NULLとだけ書くと整数のゼロを渡してしまうかもしれないからだろ
intとポインタのサイズが同じかつNULLのビット表現がintの0と一致するという限られた環境の下ではたまたま動くかもしれないが
0530デフォルトの名無しさん2008/06/01(日) 21:35:21
もっとも新しく追加したデータが0番に来て、データの削除は古い方から行うにはどんなSTLを使えばいいですか
0531デフォルトの名無しさん2008/06/01(日) 21:37:01
> どんなSTL
なんか斬新だな

dequeでいいんじゃないか
0532デフォルトの名無しさん2008/06/01(日) 21:46:37
トンクス
0533デフォルトの名無しさん2008/06/01(日) 22:26:52
シリコングラフィックのSTLを使え!
0534デフォルトの名無しさん2008/06/01(日) 22:56:37
>>530
boost/circular_buffer
0535デフォルトの名無しさん2008/06/01(日) 23:40:50
メソッドの宣言にて
void Hoge() throw (HogeException){
}
として、VC++にてビルドすると

C++ の例外の指定は無視されます。
関数が __declspec(nothrow) でないことのみ表示されます。

という警告が出ます、
メソッドの例外型制限は VC++ 以外の環境でもサポート外なのでしょうか
よろしくお願い致します。
0536デフォルトの名無しさん2008/06/01(日) 23:46:10
VC++が実装してないだけ
0537デフォルトの名無しさん2008/06/01(日) 23:46:16
>>535
gccでは使える
でもそれほど役に立たない機能だぞ
0538デフォルトの名無しさん2008/06/02(月) 00:25:17
>>536
>>537
ありがとうございます。
スローする例外を明示したかったのですが、
http://msdn.microsoft.com/ja-jp/library/sa28fef8(VS.80).aspx
を見た感じ、将来ではサポートする事を匂わせてますね。
0539デフォルトの名無しさん2008/06/02(月) 00:29:09
正直だれも使ってないから当面は実装されないだろ
0540デフォルトの名無しさん2008/06/02(月) 01:16:35
exception クラスを継承する時に使わざるを得ないけどな。
0541デフォルトの名無しさん2008/06/02(月) 01:20:31
C++でものすごく初歩的な質問なんですが・・・

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

みたいな組み込み型の配列を関数に引数として渡すにはどうしたらいいんでしょう?
vectorならそのまま参照でもコピーでもできるんですけど組み込み型はどうにもうまくいかなくて。
0542デフォルトの名無しさん2008/06/02(月) 01:30:23
void func(int *a)
{
...
}

int main()
{
int a[] = {0,1,2,3...};
func(a);
return 0;
}

もし関数内で配列を弄らないなら
void func(const int *a);
と宣言しとけばいい
0543デフォルトの名無しさん2008/06/02(月) 01:38:58
それだけじゃサイズが分からないからサイズも渡した方がいい。

#define ELEMOF(array) (sizeof (array) / sizeof (array)[0])
void func(const int *a, size_t n) { ... }
func(a, ELEMOF(a));
0544デフォルトの名無しさん2008/06/02(月) 02:06:16
>>542-543
どもです。
やっぱり組み込み型はサイズを自動的には受け渡せないんですね。
vector では受け取った関数内で size を確認できるのに
組み込み型は sizeof の結果が変わってしまうので困ってました。
0545デフォルトの名無しさん2008/06/02(月) 02:55:32
>>541
テンプレートという手もありだよ。
template<typename T>
void func(T const& a) //中身を書き換えるなら当然T&で
{
...
}
これなら関数内ではsizeof a / sizeof a[0]もできる。
以下蛇足。Boost.Rangeを使ってboost::size(a)などと書けば、
組込配列も渡せるし、std::vectorも渡せるようにできる。
0546デフォルトの名無しさん2008/06/02(月) 07:11:14
俺もBoost.Rangeが良いとは思うけど、まず基本のbegin,endを覚えた方が良い。

void func(const int* begin, const int* end) { ... }
0547デフォルトの名無しさん2008/06/02(月) 11:10:55
この前valarrayについて質問したものです。
valarray va(10);
log(va);
とか出来ますが、これは、自分で作ったクラスに対してlogとかsinとかを適用できるようにすることが
できるということだと思うのですが、どうやればよいですか?
valarrayのソースを見てみたけどよくわからんかったス
0548デフォルトの名無しさん2008/06/02(月) 12:41:38
>>547
普通に
Hoge log(Hoge x){ ... }
っていう関数を新たに定義すればいいのでは?
0549デフォルトの名無しさん2008/06/02(月) 12:44:25
データ読み込みに関する質問です。
csvファイルからデータを読み込むときに、一行目を飛ばして二行目から読み込みを始めたいと思い、
以下のようにプログラムを書きました。


/**** データ読み込み ****/
fscanf(fl,"\n"); //一行目(V1とか書いてあるところ)とばす
for(n = 0; n < P; n++){
以下配列に読み込み

fscanf(fl,"\n"); のところで一行飛ばしてから、for文で読み込んでいこうと思ったのですが、
うまくいきませんでした。

自分なりに調べてみたのですがうまくいきませんでした。ご教授よろしくお願いいたしますm(_ _)m
0550デフォルトの名無しさん2008/06/02(月) 12:47:17
>>548
たしかにそれでも出来ますが、valarrayのソース内にはそういう関数定義はないみたいなんですが、
やっぱり普通に定義しないとだめですよね?

0551デフォルトの名無しさん2008/06/02(月) 12:51:26
>>549
>fscanf(fl, "\n");
そのように書いても、一行飛ばすという意味にならない。
なぜこれで一行飛ばせると思ったのか?
教科書やリファレンスにそう書いてあったか?
カンでプログラミングしないこと。

while (fgetc(fl) != '\n') ;
などとすれば次の行まで読み飛ばせる (本当は EOF もチェックした方がいいけど)
0552デフォルトの名無しさん2008/06/02(月) 12:56:32
>>550
どの処理系か知らないけど、うちの C:\Program Files\Microsoft Visual Studio 8\VC\include\valarray には

>template<class _Ty> inline
>valarray<_Ty> log(const valarray<_Ty>& _Left)
>{ // apply log to each element of valarray
>_VALOP(_Ty, _Left.size(), ::log(_Left[_Idx]));
>}

って書いてあるよ
0553デフォルトの名無しさん2008/06/02(月) 13:03:28
>>551
レスありがとうございます。
fscanf(fl,"\n");
と書いて一行飛ばせると思ったのは、\nは改行を示しているために、
一行飛ばせると思ってしまいました。。もっと勉強します。
本当にありがとうございました。
0554デフォルトの名無しさん2008/06/02(月) 13:09:43
改行を読み込む ≠ 一行読み込む
0555デフォルトの名無しさん2008/06/02(月) 13:16:13
どーしても行読み飛ばしをfscanf()で書くんなら
fscanf(fl,"%*[^\n]"); /* 改行以外の文字を読み飛ばしてから */
fscanf(fl,"%*c"); /* 次の一文字(=改行)を読み飛ばす */
とかになる

fscanf(fl, "%*[^\n]%*c");
と一見書けそうに思えるが、いきなり改行が来るとジャムるのでダメ

ま、scanf()系って理解すればそんなに難しいものではないけど
初心者には鬼門だな
0556デフォルトの名無しさん2008/06/02(月) 15:41:22
DLLを作ってます。本来VBAから呼ぶのですが、DLLのコードをデバッグするため
コール元をVCで作成してるいんですが、
「test.obj : error LNK2019: 未解決の外部シンボル __imp__CareerDataRead が関数 _main で参照されました。」
がでます。testはDLL用テストプロジェクトです。
下記はtest用DLLソースです。
extern "C" __declspec (dllimport) int CareerDataRead(char *chrFileName);

int main()
{
CareerDataRead("test.c");

}
なにが足りないのでしょうか?
0557デフォルトの名無しさん2008/06/02(月) 15:57:34
インポートライブラリのリンク
0558デフォルトの名無しさん2008/06/02(月) 15:58:33
>>556
DLLをビルドしたときに出来たインポートライブラリをコール元にリンクする
05595562008/06/02(月) 16:05:54
>>557
>>558

即レスありがとうございます。
インポートライブラリのリンクとのことですが、
�@プロパティページの「Frameworkと参照」の「参照」にて当該libファイルを設定する
�A同プロパティページの「リンカ」「入力」「追加の依存ファイル」にて当該libファイルを設定する

と2通りのやり方を調べあげました。どちらもやっても結果が変わりません。

申し遅れましたがVC++2008 Expressにて開発しております。
0560デフォルトの名無しさん2008/06/02(月) 16:16:51
>>559
プロジェクトのプロパティのリンカの入力に設定するか、
ソースに #pragma comment(lib, "xxxxxx.lib")
を追加する。
0561デフォルトの名無しさん2008/06/02(月) 16:18:43
libファイルの場所は問題ないね?
そのDLLの関数はCリンケージでexportしてるね?
05625562008/06/02(月) 16:38:47
>>559の�@は違う気がしたので
>>560さんの指摘は�Aとお見受けしまた。pragmaの方は試してないのですが、なぜ前者の
方でうまくいかないのか謎です。
>>561
ソリューションは以下の構成下にあります。
ExcelVBA
 Debug ←ここにlibファイルがあります。
ExcelVBA
   Debug
test
よってリンカの「入力」「追加の依存ファイル」より「ExcelVBA.lib」を設定してあります。
また、リンカの「全般」に「追加のライブラリディレクトリ」というのがあったので
上記のライブラリがあるパスをフルパスで設定しました。

が、あいかわらず未解決がでます。

>>561
DLLのエクスポートですが

#define DllExport extern "C" __declspec (dllexport)
DllExport int WINAPI CareerDataRead(char *chrFileName);

を先頭につけており、同関数の中身を return 128;
でExcelから呼び出した場合128が却ってきたことを確認しています。
なお、これから複雑な処理を書くためVBAから結果のみみてデバッグは危険かと思い
ダミーコールプログラムをVC++で書いてる次第でございます。
05635562008/06/02(月) 16:43:54
リンクのコマンドラインというところにリンクオプションっぽいのを発見したので貼り付けてみます。

/OUT:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug\test.exe"
/INCREMENTAL /NOLOGO /LIBPATH:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug"
/MANIFEST /MANIFESTFILE:"Debug\test.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/DEBUG /PDB:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug\test.pdb" /
SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86
/ERRORREPORT:PROMPT excelvba.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
0564デフォルトの名無しさん2008/06/02(月) 16:52:00
WINAPI つけろ
windows.h のインクルードもね
0565デフォルトの名無しさん2008/06/02(月) 16:56:39
>>556
export側では呼び出し規約がWINAPI
import側はWINAPIが抜けてる(んでcdeclを仮定している)
正しい方に統一汁

dumpbin.exeやバイナリエディタでDLLやlibの中身をのぞいたりすることも
してみると良い
呼び出し規約が違えばライブラリに埋め込まれるリンカ用の名前も変わるから
見りゃすぐ分かるよ
05665562008/06/02(月) 17:06:12
猛烈に感動してます。先週からはまってて解決できなかったのでありがとうございます。

ちなみに下記のように修正しました。
#include <windows.h>

// extern "C" __declspec (dllimport) int WINAPI CareerDataRead(char *chrFileName);

#define DllImport extern "C" __declspec (dllimport)
DllImport int WINAPI CareerDataRead(char *chrFileName);

int main()
{
CareerDataRead("test.c");

}
05675562008/06/02(月) 19:03:10
連投ですいません。
↑の実際の処理手法を調べていました。
処理内容はファイル(テキストファイルで行ごとにタブ区切り)を読み込んで、ある一部分を集計するように
したいのですが、ファイルを読み込む方法として
�@fopen fget等C言語を使用する。
�Aifstreamを使用する。
�BCreateFile ReadFile等 Win32を使用する。
�CMFCの利用(すいません、調べきれてません)

などなどやり方が多くありどれが最適かよくわかりません。
元々VBAでやっていた集計が遅いとのことなのでスピードアップが目的なのですがどのやり方がよいか、
こんなのが一般的だなどアドバイスお願いします。
0568デフォルトの名無しさん2008/06/02(月) 19:10:35
>>567
MFCは除外するとして、WinAPIは行単位の読み込み関数がないから敷居が高いんでない?
ifstreamを使うかfopenを使うかは習熟度次第。
読み込むファイルが数値だけの書かれたテキストファイルならどっちでもいいでしょ。

処で、なんでExcel自身に処理させないの?
tsvを読み込むのも集計するのもExcelでできると思うのだけど。
05695662008/06/02(月) 19:18:49
>>568
レスありがとうございます。
ifstreamがC++っぽいらしいのでそれで挑戦します。
ちなみにExcelVBAで処理を行うと1ファイル500行ほどで5万ファイルほど集計をかけなければならないため
(この5万ファイル中で項目によりベスト5、ワースト5等を決めます)
表示を切ったりセルに書き込む処理を抑制しても、処理に15分から20分ほどかかってしまいます。
VBAでいろいろな努力をした結果、1ファイルの処理をDLLで計算させると速いと聞いたのでいま苦戦中です;;
0570デフォルトの名無しさん2008/06/02(月) 19:19:01
VBの速度が分からないけど(VBも処理速度を意識して書けば早い)
場合によっては awk でも実用的な速度になるかもしれない
興味があれば「gawk」でググれば見つかると思う

# こんな感じ
BEGIN{FS="\t"}
{if(NF>=3) sum+=$3} // 3番目のレコードの総和
END{print sum}
05715682008/06/02(月) 19:25:27
>>569
なるほど、ちょっとした量だな。
できれば、DLLにするよりも単体のプログラムにした方がらくだとは思うのだけれど……
あぁそうか、DLL作成のノウハウは(ここで)得ているのか。
0572デフォルトの名無しさん2008/06/02(月) 19:26:42
エクセルから呼び出せなきゃいけないんだな
0573デフォルトの名無しさん2008/06/02(月) 19:32:39
>>567
サンプルデータを用意してくれれば挑戦してみたい
どんな入力(サンプルデータ)に対してどんな値を返せばいいのかを教えてくれれば
C言語でやってみます

要するに関数プロトタイプとサンプルデータ下さいって事です
0574デフォルトの名無しさん2008/06/02(月) 19:35:00
Win32が最速。 C++はWin32を利用している。
0575デフォルトの名無しさん2008/06/02(月) 19:45:55
>>574
そして車輪の再生産ですね?わかります。
0576デフォルトの名無しさん2008/06/02(月) 19:47:37
まー、Windowsの開発なら、それが無難だろう
生産性重視なら他の言語でもいいが、C++にはパフォでは絶対勝てないな
0577デフォルトの名無しさん2008/06/02(月) 19:49:05
>>570
awkは以前Unixの処理系でやりましたが挫折しました。

>>571
初心者ですがこれも経験だと思ってチャレンジします。

>>572
集計結果が表やグラフで表示するため保存形式やドキュメントの流用性を考えるとExcelが有効だと考え
ました。

>>573
タブ区切りのデータが8個あり最終は改行です。

1 コメント 300 400 500 600 800 900
2 コメント 200 200 30 6 800 90000
3 コメント 350 100 450 600 20 500
:
     (500行ほどあります)

↑このファイルが5万ほどありますが、ファイル指定は親のVBAからします。つまりファイル名を入力として
最終データの最高値、最小値、平均の3つを返せればそれを利用して他の処理もできると考えてます。
05785662008/06/02(月) 19:49:55
↑は566でした。
05795682008/06/02(月) 19:54:56
>>577
VBAでファイルを読み込んで、VBAでExcel関数を使って集計するのは試した?
ファイル数が多いから微妙だけど、VBAを使いこなせていればそれなりの時間で処理できそうだけど。
0580デフォルトの名無しさん2008/06/02(月) 19:56:42
>>577
5万ファイルはxlsじゃなくてtsvファイルってこと?
んで、集計結果もエクセルで扱いやすい形式であればよい?
0581デフォルトの名無しさん2008/06/02(月) 19:59:49
>>577
6種の項目すべてについて最高値・最小値・平均を求めるとして
返すのは一番左の数値?それとも最高値・最小値?

int CarrerDataRead(const char *filename, long *max0, ... , long *max5, long *min0, ... , long *min5, long *ave0, ... , long *ave5);
こんなん?引数の数が半端無いよw
0582デフォルトの名無しさん2008/06/02(月) 20:01:19
反復とかさせればいいだろw
0583デフォルトの名無しさん2008/06/02(月) 20:04:39
>>582
VBAからの呼び出し時に配列を ByRef で渡す方法があれば簡単になるんだけど
その方法を知らないんだ
0584デフォルトの名無しさん2008/06/02(月) 20:05:00
>>579
ご指摘の内容はWorksheetFunctionのことだと思われます。が合計、平均等の処理は
当該処理を利用させてもらいました。おそらくダイエット可能な場所はほとんどやり尽く
した感があったためDLL化とうい道を選択しました。
実際算出しなければいけないデータは平均、最高値、最低値だけでないためExcel関数
の範疇を超えております。
0585デフォルトの名無しさん2008/06/02(月) 20:05:10
ファイルの入出力はWin32使った方が良い。
速度も、安定性もアップする。
なんか開けるすうに制限あるし、不安定な動作することがある c++
05865662008/06/02(月) 20:05:54
↑566でした。
0587デフォルトの名無しさん2008/06/02(月) 20:07:34
なるほど、自分のバグを棚に上げて言語批判ですね、判ります。
そりゃぁ、バッファリングしないAPIなら速いでしょうね。早くはありませんが。
つーか、ハンドル閉じ損ねても100や200じゃ問題出ませんもんね。
0588デフォルトの名無しさん2008/06/02(月) 20:09:09
>>587
なに、その地雷コードw
0589デフォルトの名無しさん2008/06/02(月) 20:09:20
バグじゃなくて200個くらいファイルにアクセスすると無視されるよ C++の仕様 
0590デフォルトの名無しさん2008/06/02(月) 20:09:51
一度にそんなにファイルを開く方がおかしいだろ。
0591デフォルトの名無しさん2008/06/02(月) 20:10:29
もしかして:
ファイルクローズはデストラクタ任せ
0592デフォルトの名無しさん2008/06/02(月) 20:10:55
C++はバッファ管理があまいから、自分でそのつど制御した方が断然速い
05935662008/06/02(月) 20:10:56
>>581
データは各行の8項目の最終データのみ対象です。返すのは3つのデータです。(最高、最低、平均)
int CarrerDataRead("ファイル名"、結果の配列)
がベストと考えてます。ただVBAの方で受けられる型とかの検証はまだしてません。すいません。
0594デフォルトの名無しさん2008/06/02(月) 20:12:14
>>593
つまり、最終カラム?
0595デフォルトの名無しさん2008/06/02(月) 20:17:24
まずは、サンプルデータ作成コード
#include<stdio.h>
#include<stdlib.h>

int main(void){
int i, j, k;
FILE *fp;
char filename[FILENAME_MAX];

for(i=0;i<500;i++){ // とりあえず50000じゃなくて500
sprintf(filename, "temp/dat%05d", i+1); // tempというディレクトリは予め作っておいて下さい
printf("%s\n", filename);
if((fp=fopen(filename, "w"))==NULL) exit(1);
for(j=0;j<500;j++){
fprintf(fp, "%d\tコメント", j+1);
for(k=0;k<6;k++) fprintf(fp, "\t%d", rand());
fprintf(fp, "\n");
}
fclose(fp);
}
return 0;
}
0596デフォルトの名無しさん2008/06/02(月) 20:25:17
>>570
俺もこの手の内容ならawk か perlあたりでいいかなと思ったんだけどね。
UN*Xユーザはなかなか理解されないのだろうかorz
0597デフォルトの名無しさん2008/06/02(月) 20:37:29
awkで書けば、こんなもんだよ
awkは全て実数だし配列処理が遅いことでも有名なので、
awkが遅すぎると思えるならperl/ruby/pythonあたりを試すといいだろう

別解としては、TSVなら簡単にDBに取り込めるはずなので、
SQLに集計処理をやらせる手もある

#!/usr/bin/awk -f

BEGIN {
    from = 3
    to = 9
}
NR == 1 {
    for (i = from; i < to; i++)
        amax[i] = amin[i] = asum[i] = $i
}
NR > 1 {
    for (i = from; i < to; i++) {
        if ($i > amax[i]) amax[i] = $i
        if ($i < amin[i]) amin[i] = $i
        asum[i] += $i
    }
}
END {
    for (i = from; i < to; i++) printf("%d\t", amax[i])
    printf("\n")
    for (i = from; i < to; i++) printf("%d\t", amin[i])
    printf("\n")
    for (i = from; i < to; i++) printf("%g\t", asum[i]/NR)
    printf("\n")
}
0598デフォルトの名無しさん2008/06/02(月) 20:40:48
>>597
スレ違い感が否めないが、$8だけでいいらしいよ。
0599デフォルトの名無しさん2008/06/02(月) 20:42:03
>>598
よく読んでなかった

まあ、俺がいいたかったのは、わざわざC/C++で書く必要がある仕事には見えない
ってことだったんだけどね
0600デフォルトの名無しさん2008/06/02(月) 20:43:38
>>583
>>402そんな面倒ではないぞ。
0601デフォルトの名無しさん2008/06/02(月) 20:48:39
そこは同意。
だがもしかするとみんなそれを理解したうえで、主のDLLで
何とかしたいという要求に答えたいだけなのかもしれないや。

とりあえずawkでやってみたけど、大して速くないものの処理が終わり、
テストデータの大きさが2ギガあったことにびっくりしつつ削除してオワタ。
06025732008/06/02(月) 21:41:47
作ってはみたけど、一つのファイルに対して best5、worst5、平均 の計11個求めるんじゃなかったみたいだね orz
06035732008/06/02(月) 23:14:20
#include<stdio.h>
typedef long value_t;
int value_get(FILE *fp, value_t *value){
return fscanf(fp, "%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%ld", value)==1;
}
int CareerDataRead_internal(const char *filename, value_t *best, value_t *worst, value_t *average){
FILE *fp;
long i, sum=0;
value_t value, maximum, minimum;
if((fp=fopen(filename, "r"))==NULL) return 0;
if(!value_get(fp, &value)){
fclose(fp);
return 0;
}
maximum=minimum=value;
sum+=value;
for(i=1;;i++){
if(!value_get(fp, &value)) break;
if(value>maximum) maximum=value;
if(value<minimum) minimum=value;
sum+=value;
}
fclose(fp);
*best=maximum;
*worst=minimum;
*average=sum/i;
return i;
}
__declspec(dllexport) int CareerDataRead(const char *filename, value_t *result){
return CareerDataRead_internal(filename, &result[0], &result[1], &result[2]);
}
0604デフォルトの名無しさん2008/06/03(火) 00:12:02
>>603だけでなく、ソース貼る人全員に対してだけど、
全角空白でもいいからインデントしてくれるとありがたい。

&nbsp;だと半角空白のままインデント出来るから尚いいけど、
こっちは文字数制限に掛かりやすくなるからね。
0605デフォルトの名無しさん2008/06/03(火) 00:12:43
SQLなんちゃらにぶち込んだほうがよくね?
0606デフォルトの名無しさん2008/06/03(火) 00:15:05
SQLite?
0607デフォルトの名無しさん2008/06/03(火) 00:18:15
Cの系譜は{}でインデントが導出できるから必要ないんでないのかなー。
自分でindent叩くとかindent-regionするとかさー
■ このスレッドは過去ログ倉庫に格納されています