トップページ⇒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
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するとかさー
0608デフォルトの名無しさん2008/06/03(火) 00:25:15
indent-regionはともかく、わざわざ回答側にindent叩かせるなってこと。
0609デフォルトの名無しさん2008/06/03(火) 00:39:27
Core Duo 1.66 GHz / 1 GB Mem という環境で、直列の ifstream 実装を
試したところ 3 分弱。結構かかるねー。
0610デフォルトの名無しさん2008/06/03(火) 00:44:13
ぶっちゃけこの程度の計算はゴミだから大半はI/Oの時間でしょ
ifstreamなんて糞みたいに遅いから、わざわざC++使ってもちっとも速くならないと
思う
0611デフォルトの名無しさん2008/06/03(火) 00:47:12
#include <stdio.h>
#include <stdlib.h>
void hyouji(int x);
main()
{
int i,x;
char hikisu[];
printf("数値を入力してください(1-52):");
scanf("%d",&x);
hyouji(x);
for (i=1; i <= x; i++){
printf("%d %c",i,hikisu[i]);
}
}
void hyouji(int x)
{
FILE fp;
int i;
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for (i=1; i <= x; i++){
fscanf(fp, "%c", &hikisu[i]);
}
fclose(fp);
return;
}
以上のプログラムで『LightC』を使ってコンパイルしようとしても上手くいきません。
どの辺りが間違っているのでしょうか?
『LightC』
ttp://www.tamasoft.co.jp/lc/index.html
0612デフォルトの名無しさん2008/06/03(火) 00:48:03
iostreamは遅いとの噂。
少なくともVC6の頃は鼻血出そうなくらい遅かった。
0613デフォルトの名無しさん2008/06/03(火) 00:50:59
エラーメッセージくらいな・・・
0614デフォルトの名無しさん2008/06/03(火) 01:06:23
#include <stdio.h>
#include <stdlib.h>
void hyouji(int x);
main()             ←戻り値の型指定が無い
{
int i,x;
char hikisu[];         ←サイズが決まってない
printf("数値を入力してください(1-52):");
scanf("%d",&x);
hyouji(x);
for (i=1; i <= x; i++){
printf("%d %c",i,hikisu[i]);
}
}
void hyouji(int x)
{
FILE fp;             ←普通ファイルポインタを使うので*fp
int i;
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for (i=1; i <= x; i++){
fscanf(fp, "%c", &hikisu[i]);  ←hikisuなどと言うものはこの関数内に存在しない
}
fclose(fp);
return;
}

ぱっと見た感じこんなもの
0615デフォルトの名無しさん2008/06/03(火) 01:07:37
>>608
vimで
ggVG=
とやればよいよ。VSなら}を書き直したらそれでやってくれなかったっけ?
0616デフォルトの名無しさん2008/06/03(火) 01:12:31
>>611
基礎から学べ
0617デフォルトの名無しさん2008/06/03(火) 01:28:45
>>615
わざわざそれだけのためにエディタ起動させるのか。
06186112008/06/03(火) 01:31:43
>>611のエラーコードを書き忘れてました・・・

test.c(7): エラー C.2530: 変数 hikisu のサイズが不明です
test.c(5): 警告 C.5280: 関数 main に return 文がありません
test.c(19): エラー C.2920: struct _FILE/* を struct _FILE に変換することはできません
test.c(24): エラー C.2130: 識別子 hikisu が未定義です
test.c(26): エラー C.2920: struct _FILE を struct _FILE/* に変換することはできません
0619デフォルトの名無しさん2008/06/03(火) 02:13:20
>>617
だってビルドエラーとか、半端なソースの場合とか、動かす前に
見なきゃじゃん。
エディタ起動すらめんどくさがるとかどうやってソース書いてんの?
06206112008/06/03(火) 02:16:05
>>614のヒントを元に>>611を修正してみました。
#include <stdio.h>
#include <stdlib.h>
void hyouji(int x);
char main(char hikisu[])
{
int i,x;
printf("数値を入力してください(1-52):");
scanf("%d",&x);
hyouji(x);
for (i=1; i <= x; i++){printf("%d %c",i,hikisu[i]);}
}
void hyouji(int x,)
{
FILE *fp;
int i;
char hikisu[52];
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for (i=1; i <= x; i++){fscanf(fp, "%c", &hikisu[i]);}
fclose(fp);
return;
}
しかし、それでも以下のようなエラー文が出ます。
test.c(4): 警告 C.5280: 関数 main に return 文がありません
test.c(19): エラー C.2150: == 演算子の引数が正しくありません
一体どこにエラーがあるのでしょうか・・・
0621デフォルトの名無しさん2008/06/03(火) 02:44:28
#include <stdio.h>

void f(int **p){
int x[2]={1,2};
*p=x;
}

int main(void){
int *p;
f(&p);
printf("%d\n",p[0]+p[1]);
return 0;
}

上のプログラムの誤りを指摘せよという問題が出たのですが、
どこが間違っているのかよくわからないので教えてください。
おそらくp[0],p[1]のあたりが違うのだと思うんですが・・・
0622デフォルトの名無しさん2008/06/03(火) 02:46:40
>>620
>char main(char hikisu[])
ただ付ければ良いって物でもないだろ。
一度「ちゃんとした」入門書を買ってきて勉強したほうがいい。

>test.c(4): 警告 C.5280: 関数 main に return 文がありません
「return文がない」と言われているのだから、どこかにreturn文を追加すれば
いいのではないか、というくらいは想像つかないか?
0623デフォルトの名無しさん2008/06/03(火) 02:48:37
>>620

※1
char main(char hikisu[])
↓
int main(int argc, char** argv)

※2
printf("%d %c",i,hikisu[i]);のhikisuが不明

※3
main関数の最後にreturn 0;を付ける

※4
void hyoujiと関数の戻り値がvoidになっている。
戻り値を使わないのなら、最後のreturn;は必要ないです。

※5
void hyouji(int x,)
↓
void hyouji(int x)
0624デフォルトの名無しさん2008/06/03(火) 02:49:14
>>621
つ ヒント「ローカル変数の寿命」
06256232008/06/03(火) 03:12:28
定性

※2
printf("%d %c",i,hikisu[i]);のhikisuが不明

と書いたけど、mainの引数を使いたいっぽいのですよね。
mainの引数を使うなら、
argcの方に引数の数が入ってるから、その数を参考にしてその数をオーバーする事のないようにして、
printf("%s", argv[i]);
これみたいに表示かな。
06261/22008/06/03(火) 03:20:56
#include <stdio.h>
#include <stdlib.h>

void hyouji(char*, size_t);

int main()
{
char *hikisu;
size_t size;

while(1){
printf("数値を入力してください(1-52):");
scanf("%d", &size);
if(size > 0 && size < 53) break;
else printf("サイズを超えています\n");
}

hikisu = (char*)malloc(size * sizeof(char));
if(NULL == hikisu){
printf("メモリが確保出来ません\n");
exit(1);
}

hyouji(hikisu, size);

free(hikisu);

return 0;
}
06272/22008/06/03(火) 03:21:17
void hyouji(char *hikisu, size_t size)
{
FILE *fp;
int i;
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for(i=0; i < size; ++i){
fscanf(fp, " %c", &hikisu[i]);
printf("%2d: %c\n", i+1, hikisu[i]);
}
fclose(fp);
}

やりたいんだろうなと言う事を考えたらこんな感じになるかな
homework.txtの中身を知らないからその辺は変わるかも知れないけど
0628デフォルトの名無しさん2008/06/03(火) 04:17:38
問題をより小さな問題に切り分けていくことが出来ないのが、一番致命的。
06296112008/06/03(火) 09:19:09
>>回答してくださった皆様
ありがとうございます、そして本当にご迷惑をおかけしました・・・

>>614-627とテキストを見直してもう一度自分で考えてみようと思います。
0630デフォルトの名無しさん2008/06/03(火) 16:57:39
#include <iostream>
using namespace std;

int main(void)
{ cout << "Hello" << endl; }

上記のソースをコンパイルして、 c:\>hello.exe > hello.txt
のように実行すれば、テキストファイルができるのですが、
出力させたいのがテキストではなく、バイナリデータの時はどうすれば良いのでしょうか?

cout << binary_data;
とすると、意図しないデータが出力されてしまいます。

どうすればバイナリデータを変換させないでそのまま出力させることができるのでしょうか?
どなたか、優しい方いましたら教えて下さい。
携帯から書き込んでいるので、見にくかったらすみません。
0631デフォルトの名無しさん2008/06/03(火) 17:45:51
>>630
バイナリモードにすればよろしかろ。
0632デフォルトの名無しさん2008/06/03(火) 17:48:55
>>631
その、バイナリモードってやつにはどうすればできるのでしょうか?
0633デフォルトの名無しさん2008/06/03(火) 17:53:18
>>632
cout バイナリとかでググればいいんじゃね?
0634デフォルトの名無しさん2008/06/03(火) 17:55:32
>>632
Windowsだよね。__setmode(__fileno(stdout), _O_BINARY)でOK。
0635デフォルトの名無しさん2008/06/03(火) 18:05:47
バイナリデータ書くなら << はダメだ
char*にキャストしてwrite()とかするんだね
0636デフォルトの名無しさん2008/06/03(火) 18:15:31
オイオイ
0637デフォルトの名無しさん2008/06/03(火) 21:32:59
>>636
俺なんかおかしいこと言った?
バイナリ出力ならエンコード変換も書式フォーマットも改行制御も要らない
つまりiostreamは完全に余計な邪魔者でしかない

ostream::write()がマシだと思うが
streambufを使う方がマシで、
本当はiostreamなんて使わないのが一番いい
0638デフォルトの名無しさん2008/06/03(火) 22:05:43
バイナリを文字列に変換して<<する
0639デフォルトの名無しさん2008/06/03(火) 22:33:51
>>638
fwrite()一発で済む仕事でなぜわざわざそんなことをやる
明らかに遅く、特に得るものがあるとも思えない
0640デフォルトの名無しさん2008/06/03(火) 22:36:30
<< で連結して書けるのは、ソース中の記述と
実際の出力との対応を分かりやすくできて、メリットだと思うけどね。
0641デフォルトの名無しさん2008/06/03(火) 22:40:13
よくわからんなー
32bit整数をバイナリ出力するときとか、Cならアドレス取って4byte書き出す
わけじゃん
iostreamの作法ではどうするの?
0642デフォルトの名無しさん2008/06/03(火) 23:13:28
え?バイナリデータをバイナリエディタみたいに数値として表示するんじゃないの?
0643デフォルトの名無しさん2008/06/03(火) 23:15:39
>>642
意味が分からない
バイナリビューワなら、出力は「テキスト」じゃないか
>>630は「バイナリデータを出力したい」と言ってるんだぞ

質問者の意図を理解してなかったの?
06446302008/06/04(水) 00:00:25
>>630です。
あれから、色々頑張ってみたのですが、なにぶん初心者な者で、かなりてこずりました。
最終的には _setmode でなんとかできました。
fwrite で書き出したファイルとも一致するので、とりあえずはこれで良しとします。

色々と教えて下さった皆さん、どうもありがとうございました。
0645デフォルトの名無しさん2008/06/04(水) 00:04:53
>>644
分かってると思うけどC++でもfwrite()は普通に使っていいんだよ
0646デフォルトの名無しさん2008/06/04(水) 00:30:57
使ったら負けかなと思ってる
0647デフォルトの名無しさん2008/06/04(水) 00:46:23
>>646
参考までに聞くけど、fwrite()の替わりに何使ってるの?

fwrite()なら
int a = 0xdeadbeaf;
fwrite(&a, sizeof a, 1, fp);
で済むけど

ostream::write()やstreambuf::sputn()はキャストしなきゃいけないから
stream.write(reinterpret_cast<char*>(&a), sizeof a);
とかになるよね

コードは長い、汚い、その上遅い
0648デフォルトの名無しさん2008/06/04(水) 00:55:24
oven::streambuf_writer
0649デフォルトの名無しさん2008/06/04(水) 00:59:26
boostですらないのかw
0650デフォルトの名無しさん2008/06/04(水) 01:11:14
fwrite系をパックした自作クラス使ってるわ。
必要ならFILEポインタからstreamオブジェクトに
キャストできるし、f系の方が便利よね。
0651デフォルトの名無しさん2008/06/04(水) 01:12:01
fopenでいいじゃん
0652デフォルトの名無しさん2008/06/04(水) 09:44:44
変数のオーバーフローを検知する方法を教えてください
0653デフォルトの名無しさん2008/06/04(水) 09:51:42
こんなん?

if ( MAX - 値 < 変数)
 変数+値はオーバーフローしちゃうよヽ(゚∀゚)ノ
0654デフォルトの名無しさん2008/06/04(水) 14:57:29
インラインasmでオーバーフロービットをチェックが正解かな?
0655デフォルトの名無しさん2008/06/04(水) 17:37:47
if((rhs > 0) && ((lhs + rhs) < lhs)){ ; }
0656デフォルトの名無しさん2008/06/04(水) 19:20:07
VC++ で開発する際に、常に警告レベルを最高に設定しています。

警告レベル最高だと、未初期化の変数が使用される可能性がある場合に
ビルド時に警告が出力されますが
構造体変数の初期化方法に困っています
使用直前で変数宣言すべきか、構造体1つ1つに初期値をセットすべきか
他に何かスマートな方法があるのでしょうか、
よろしくお願い致します。
■ このスレッドは過去ログ倉庫に格納されています