07/06/25 12:01:46
エスケープシーケンスやWin32APIなどの環境依存な物でもOK。
ただしその場合、質問者は必ず、環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.38【環境依存OK】
スレリンク(tech板)
【アップローダー】(質問が長い時はココ使うと便利)
URLリンク(kansai2channeler.hp.infoseek.co.jp)
2:デフォルトの名無しさん
07/06/25 12:04:06
>>1乙
3:ちんこ
07/06/25 12:33:43
乙
4:デフォルトの名無しさん
07/06/25 12:36:12
チン腰ね
5:デフォルトの名無しさん
07/06/25 13:26:07
/ / / ヽ ヽ
/^ 7 / // i /| .ト、 !ハ .
,′// }. |ハト、{ヽ! ヽ! ヽト/ハ ! !
三 | / / | ハ ,=、 =、 ☆ | |
_| / ミ /ノ,, ,, ___ ,, | ! j|
\ /三L」 ミ / 二コ、ヽ . _ .ノ ,イ / . ′
X/ .| | ミ / xく | > ┬ イリ. / /
// \ | |__ / .!斗―/.! / ./ /__{
.{_ __ / ̄ヽj 从| トイヽ_/{ { ∧
 ̄_ {___人 / /` .。ノ ___ \
//∨ } \< / ′ ※亠‐┐ 〉
//ミ ノ_人 \{ { j!| }|/!
6:デフォルトの名無しさん
07/06/25 15:08:41
C言語 XP Borland C++ Compiler 5.5
ファイルから別のファイルに内容をコピーする場合
コピー元のファイルを開いて中身を配列に格納してコピー元のファイルを閉じ、
コピー先をファイルを開いて配列に格納した内容をコピー先に送ってコピー先のファイルを閉じる
ってやり方でOKでしょうか?
それともコピー元とコピー先のファイルを一緒に開いて直接コピーする事は可能ですか?
7:デフォルトの名無しさん
07/06/25 15:11:17
同時にオープンしてても大丈夫
8:デフォルトの名無しさん
07/06/25 15:25:43
>>6
と言うかメモリに収まりきらない巨大なファイルをコピーする場合は
同時にオープンするしかないでしょ。
seekg()とかでちょっとずつコピーする事もできるけど現実的じゃないし。
9:デフォルトの名無しさん
07/06/25 15:28:02
有難うございます
同時にファイルを開く場合、書き方としてはこれで大丈夫でしょうか?
FILE *fp1,*fp2;
char ch;
if((fp1 = fopen(argv[1],"r")) == NULL){
printf("ファイルを開くことが出来ません\n");
exit(1);
}
if((fp2 = fopen(argv[2],"a")) == NULL){
printf("ファイルを開くことが出来ません\n");
exit(1);
}
while((ch = fgetc(fp1)) != EOF){
fputc(ch,fp2);
10:デフォルトの名無しさん
07/06/25 15:35:53
fclose()も忘れずにな
それから"a"で開いてるのはどうして?
11:デフォルトの名無しさん
07/06/25 15:42:42
>>9
・引数の数チェック汁
・fgetc()はgetc()と機能は同じだがfgetc()のほうが速いことはまずない
fputc()も同様
まぁどっちもファイルコピーに使うには遅すぎだが
・つかファイルをコピーしたいんならバイナリで開け
・開けなかった時はperror()を使うと処理系定義のエラーメッセージを出してくれる
12:デフォルトの名無しさん
07/06/25 15:46:45
>>10 w+ に変更しますた
>>11 今日、ファイル入ったばかりでまだバイナリまでいってないんす・・・
でこんな感じで書いてみたのですが、何故かコピー先のファイルから結果が表示されない・・・どちて?
int main(int argc,char *argv[])
{
FILE *fp1,*fp2;
char ch;
if(argc != 2){
printf("使用法:<プログラム名> <コピー元ファイル名> <コピー先ファイル名>\n");
exit(1);
}
if((fp1 = fopen(argv[1],"r")) == NULL){
printf("ファイルを開くことが出来ません\n");
exit(1);
}
if((fp2 = fopen(argv[2],"w+")) == NULL){
printf("ファイルを開くことが出来ません\n");
exit(1);
}
while((ch = fgetc(fp1)) != EOF)
if(fputc(ch,fp2) == EOF){
printf("ファイル書き込みエラー\n");
exit(1);
}
fclose(fp1);
while((ch = fgetc(fp2)) != EOF) putchar(ch);
fclose(fp2);
return 0;
}
13:デフォルトの名無しさん
07/06/25 15:49:49
- if(argc != 2){
+ if (argc != 3) {
それと
while((ch = fgetc(fp2)) != EOF) putchar(ch);
の前に
rewind(fp2);
入れろ
14:デフォルトの名無しさん
07/06/25 15:52:27
>>13
できました
ありがとうごぜいます
15:デフォルトの名無しさん
07/06/25 16:12:16
windows、C++Builderです。
バックアップソフトを作りたいと思ってます。
フォルダの中身を、違うパーティションにコピーするだけです。
’曜日’と’時間’だけ、タイムテーブルのようなものに
記録しておいて、時間が来たらコピーする。ということを
永久に繰り返します。
月曜日は、5:00と13:00と18時
火曜日は、5:00
水曜日は、3:00
・・・
など、曜日によって回数も様々です。
どういう仕組みを使うのが、良いでしょうか?
time_t current;
time(¤t);
で、1秒ごとに時刻を取得して比較してたら
大変ですよね。
16:デフォルトの名無しさん
07/06/25 16:14:42
基本的にはタイマー設定すると思うけど。
17:デフォルトの名無しさん
07/06/25 16:17:10
>>15
1.次のバックアップまでの時間に応じてチェックする間隔を変更する(時間に応じて2時間、30分、5分、1分のように)
2.Windows付属のスケジューラを使う
3.多少の誤差は気にせず指定時間までSleep
18:デフォルトの名無しさん
07/06/25 16:27:43
RHEL3環境で、gcc(ver 2.95.3であると思われます)
c++でcursesを使ったプログラミングをしているのですが、
string str[2]
str[0] = "hoge0";
str[1] = "hoge1";
str[2] = "hoge2";
for(int i=0; i<3; ++i){
printf("%s\n",str[i]);
refresh();
sleep(1);
}
のように行うことで出力したいのですがうまくコンパイルできません。
stirng型を出力する方法はないでしょうか?
教えてください。
19:デフォルトの名無しさん
07/06/25 16:31:49
>>18
つ str[i].c_str()
つか、君の読んでる本には載ってないのか?
20:デフォルトの名無しさん
07/06/25 16:32:52
>>18です。
追記です。
出力に●や彡を出力したいので、charではうまくいかず、
stringを使っています。
%sがchar*だからstringの出力ができないと思うのですが、
%sの代わりの変換指定子が分かりません。
お願いします。
21:デフォルトの名無しさん
07/06/25 16:34:39
>>18です。
>>19さんの書き込み見る前に>>20を書き込んでしまいました。
今試して見ます。
ありがとうございます。
22:デフォルトの名無しさん
07/06/25 16:35:08
>>18
- string str[2]
+ string str[3];
>>20
>>19を嫁
c_str()はconst char*を返すから%sでいい
23:デフォルトの名無しさん
07/06/25 16:38:53
文字列の表示に変換指定子の「%s」を使っての
ひらがな、カタカナ、漢字などの全角文字の表示に問題なかったのですが
実際は半角英数字以外使ってはいけないとかあるのでしょうか?
初心者向けの書籍だとみな半角の英語を使って説明されているので
全角文字でも問題がないのかどうか判断に困っています。
24:デフォルトの名無しさん
07/06/25 16:42:18
>>23
ためせ
25:デフォルトの名無しさん
07/06/25 17:01:14
試してOKだったけど、どうなの?って話だろうに。
>>23
char* なら、ASCII だろうと多バイト文字列だろうと問題ナス。
26:デフォルトの名無しさん
07/06/25 17:02:42
>>12
その場合
char ch;
は間違い。
int ch;
にすべし。
27:24
07/06/25 17:03:40
ああ、「問題なかった」と言ってるんだから「試せ」も糞も無いな
ごめん
実際には
・その特定のエンコーディングのソースをコンパイラが処理できるか
・実際に表示(端末に出力)した際に、その特定のエンコーディングの文字列を
端末が表示できるか
といった問題が関係してくる
まあ日本語に対応したOSや端末で、日本語に対応したコンパイラを使っている
分には通常問題が無いが、
例えばEUC-JPやISO-2022-JPやUTF-8なソースをVC++は食えない
最近のgccは-finput-charsetだの-fexec-charsetだのを適切に指定することで
多国語に対応する
28:デフォルトの名無しさん
07/06/25 17:07:16
>>18です。
>>19さん
のように行ったらできました。ありがとうございました。
私の使っている、「やさしいC++」にはc_str()は載ってませんでした。
これが分かった上でもうひとつお聞きしたいのですが、
string str[2];
str[0] = "hoge0";
str[1] = "hoge1";
str[2] = "hoge2";
char* s[2];
s[0] = str[0].c_str();
s[1] = str[1].c_str();
s[2] = str[2].c_str();
が行えません。
char*にchar*を入れているのでいけると思ったのですが。
これはなぜでしょうか?
29:デフォルトの名無しさん
07/06/25 17:08:28
>>28
>>22で指摘したのに……
配列str[]のサイズは2ではなく3にしろ
30:デフォルトの名無しさん
07/06/25 17:10:00
なんでダメかというと
char*にconst char *はそのままでは代入できないからだ
const char *s[3];
とするか(こっちが推奨)、
s[0] = const_cast<char*>(str[0].c_str());
とでも汁(こっちは非推奨)
31:デフォルトの名無しさん
07/06/25 17:11:53
>>29さん
すみません、これは単純な書きミスでした。
string str[3];
str[0] = "●";
str[1] = "●●";
str[2] = "●●●";
char* s[3];
s[0] = str[0].c_str();
s[1] = str[1].c_str();
s[2] = str[2].c_str();
としてます。
32:デフォルトの名無しさん
07/06/25 17:16:47
>>30
非推奨っつーか、やっちゃだめ
33:デフォルトの名無しさん
07/06/25 17:17:48
>>30さん
ありがとうございます。
やってみたらできました。
みなさんありがとうございました。
# 書き込む前に新しいレスがあるかリロードでチェックしなくてはいけませんね。
# 何か自分が書き込むタイミングが一歩遅いようで。申し訳ないです。
34:デフォルトの名無しさん
07/06/25 17:18:39
>>32
char *s = "hello";
と犯罪性は同じだと思うけど。
でもこれは合法だしな未だに。
35:23
07/06/25 17:20:24
>>25
>>27
詳しい説明ありがとうございます、
助かるとともに勉強になります。
36:デフォルトの名無しさん
07/06/25 17:21:18
>>34
そんな負の遺産も使っちゃダメ。
37:デフォルトの名無しさん
07/06/25 17:23:44
>>36
〃〃∩ _, ,_
⊂⌒( `Д´) < ヤダヤダ!
`ヽ_つ ⊂ノ
ジタバタ
38:デフォルトの名無しさん
07/06/25 17:54:43
main で catch(...) ってどう思います?
例外がキャッチされなかった場合、
デストラクタが実行されるかどうかは未定義で、
実際 g++ だと実行されなかったりします。
それを考えると、main で catch(...) しといた方が
安全なのかな・・・とか思うのですが。
39:デフォルトの名無しさん
07/06/25 18:03:13
#include<stdio.h>
#include<stdlib.h>
char *search_r(char *s,char *p){
char *x;
int i;
x=p;
i=sizeof(p);
while(1){
p=x;
if(*s=='\0')exit(1);
while(*s==*p){
if(*s=='\0')exit(1);
s++;
p++;
}
if(*p=='\0')break;
s++;
}
return s-(i-1);
}
int main(){
char *x;
x=search_r("konbanhasensei","hasen");
printf("%s",x);
return 0;
}
文字列pから文字列sを検索するプログラム
このプログラムで結果を 「hasensei」と表示したいのですが「sensei」となってしまいます。
どこがおかしいのでしょうか。
よろしくお願いします。
40:デフォルトの名無しさん
07/06/25 18:08:15
>>39
マンドクセーからちゃんと読んでないが
> i=sizeof(p);
sizeof(p)はポインタpのサイズ(4とか)が分かるだけだ。
pが指してる文字列の長さを測りたいのなら、strlen()を使え。
41:デフォルトの名無しさん
07/06/25 18:08:25
sizeof(p) → strlen(p)
s-(i-1) → s-i
exit(1); が凄い気になるが・・・。
NULL 返したのでいいんじゃないかな。
for 使ってないあたりも読みづらい。
42:デフォルトの名無しさん
07/06/25 18:11:37
>>40
>>41
ありがとうございます。
43:デフォルトの名無しさん
07/06/25 18:19:29
それ以外にもバグはあるけど、
まあそれは自分で確認してくれ。
44:デフォルトの名無しさん
07/06/25 21:19:09
環境はC++です
今日自分の作ったサブルーティンを上司がチェックしたみたいなんですが
この構造体はインパラメータだから値渡しにしろ
と言ってきました。
サブルーティンの引数に構造体を渡すときに値渡しって使いますか?
このサブルーティンで使っている構造体のサイズは決して小さくはありませんし、
自分的には構造体のサイズが小さくても値渡しは使わないと思っていたので
ちょっと衝撃的でした。
45:デフォルトの名無しさん
07/06/25 21:25:18
場合による
46:デフォルトの名無しさん
07/06/25 21:25:36
>>44
const参照渡しをしててそう言われたんなら上司を鼻で笑ってやれ
constのつかないポインタ渡しでもしてたんなら君も悪い
47:デフォルトの名無しさん
07/06/25 21:47:18
つうか値渡しでどうやって受け取るんだ
48:47
07/06/25 21:48:37
あぁ読み込みパラメータね
勘違いした ごめんよ
49:デフォルトの名無しさん
07/06/25 21:56:24
const ポインタ渡しするのが普通だな。
小さい構造体の場合は別な事もあるけど、
まあ場合によるな。
50:44
07/06/25 22:21:39
>>46
上司を鼻で笑ってやったら首になりました。
貰ってやって下さい。
51:デフォルトの名無しさん
07/06/25 22:24:29
>>50
早っ!
52:デフォルトの名無しさん
07/06/25 22:24:49
>>50
うちに来い。Cだが、ひどいデスマも無い。
残業代は0だけど・・・
53:デフォルトの名無しさん
07/06/25 22:43:57
>>16-17
15です。
曜日、時間でのバックアップの件でしたが、
お礼遅れてすみません。sleepで行きます。
ありがとうございました。
54:デフォルトの名無しさん
07/06/25 23:02:28
>>49
C++ならconst参照だろ
55:デフォルトの名無しさん
07/06/25 23:03:36
あ、C++ だったか。
大きな構造体って時点で C かと思ってしまってた。
56:デフォルトの名無しさん
07/06/25 23:07:00
C++です。
struct S {
int a;
int b;
int c;
};
という定義の構造体があったとして、
S s = {0};
と書いた場合、b と c が 0 になることは保証されますか?
57:デフォルトの名無しさん
07/06/25 23:09:31
されます。
58:デフォルトの名無しさん
07/06/25 23:16:54
8.5.1p7 に書いてあるね。
int() すなわち 0 で初期化される。
59:デフォルトの名無しさん
07/06/25 23:24:54
>>57,58
ありがとです。
60:デフォルトの名無しさん
07/06/26 01:00:48
C++Builderです。
builderのウィンドウで、タブ(Astandard,Additional,Win32,System,,,)
ってありますが、こういうことする場合は、どんな部品を
使用すればよいでしょうか?
61:60
07/06/26 01:03:49
タブをクリックしたら、なにか表示させたり、
追加、削除もしたいんです。
よろしくお願いします。
62:デフォルトの名無しさん
07/06/26 02:34:19
>>38
あんたの思ってるとおり、しといたほうが安全だよ。
その前に std::exception は別でキャッチしてエラー表示してね。
63:デフォルトの名無しさん
07/06/26 05:55:44
変な状態のままデストラクタが呼ばれたら、
それはそれで危険という気もしなくもない。
どっちがいいのかね?
64:デフォルトの名無しさん
07/06/26 06:36:20
例外と言えば、例外指定って使ってる?
俺は使ってない。
65:デフォルトの名無しさん
07/06/26 08:37:35
正常にインスタンスができたかどうかフラグ持っておけばいいんじゃないか
66:デフォルトの名無しさん
07/06/26 08:41:34
まあ、たとえ例外が起きても
メンバ変数が変にならないように気をつけるべきということで、
キャッチされても問題ないように作るべき、なのかな?
67:デフォルトの名無しさん
07/06/26 08:55:33
>>63,65,66
URLリンク(www.boost.org)
URLリンク(boost.cppll.jp)
「まるで例外は、正しいコードに対するミステリアスな攻撃であり、
我々が自らをその攻撃から守らなければいけないようなものであると
見なされているかのようである。 言うまでもなく、これはエラー捕捉との
健全な関係に繋がらない!」
68:デフォルトの名無しさん
07/06/26 09:00:32
>>64
boost や標準ライブラリの方針によれば、使わないほうがいいってことになる。
URLリンク(www.boost.org)
69:デフォルトの名無しさん
07/06/26 09:08:14
最適化の問題で使わない方がいいという話もあるのか。なるほど。
70:デフォルトの名無しさん
07/06/26 09:17:40
標準ライブラリで std::exception::what だけ例外的に例外指定を持ってるのは、
catch 中で別の例外起こされたら面倒だからかな?
71:デフォルトの名無しさん
07/06/26 09:23:55
>>67
確かに健全な関係ではないけど、
無視できないんだよなあ。
例外指定を普通使わない以上、
どの関数がどんな例外を投げるか
パッと見分からないことも多いし、
思わぬ例外を投げられたらそれは
ミステリアスな攻撃と思われてもしゃーない気がするよ。
全ての関数が例外を投げる可能性があるって感覚で
プログラムを組むのがいいのかね。
72:デフォルトの名無しさん
07/06/26 09:35:26
>>71
安全側に倒すという意味で、そう思ってかかってもいいだろう。
思わぬ例外を投げられてもきちんと動作するように書くべきだし、
極力そう書くことができるように言語や標準ライブラリが整備されている。
73:デフォルトの名無しさん
07/06/26 09:36:45
>>70
標準ライブラリの中でも throw() はいろんな関数についてるよ。
型付で指定してるのはグローバルな operator new () ぐらいかな?
74:デフォルトの名無しさん
07/06/26 09:44:20
>>73
あ、そうなんだ。
std::exception::what はオーバーライドすることがあるから
目立つってだけのことか。
75:デフォルトの名無しさん
07/06/26 09:46:24
>>72
Joel タンが例外嫌いなのも、そのあたりが気持ち悪いからなんだろうな。
でも、標準ライブラリやキーワードが例外投げる以上、
無視するわけにもいかないと思うんだけどね・・・。
76:デフォルトの名無しさん
07/06/26 10:26:57
>>75
あの話は戻り値についてもいっしょだろ。
ただ単に戻り値でのチェックに慣れているから、
戻り値をチェックしていないコードのほうが見つけやすいって話。
例外に慣れてしまえば、例外安全でないコードは同じぐらい
簡単に見つけられる。ただし現状では、↑の理由で他の人に
伝わらないことが多い。
敢えて言い切ってみたけど、ホントのところはちょっと自信が無い。
新しい言語をデザインするなら、 try ブロックじゃなくって
nothrow ブロックを作ればいいんじゃないかと思う。
「オレはここでは例外が飛ばないと仮定して書くぜ」っていう
ブロックね。
77:デフォルトの名無しさん
07/06/26 10:31:57
どうなんかねえ。
例外をうっかり無視するコードより、
戻り値をうっかり無視するコードの方が危険性は高いと
個人的には思うんだけど。
78:デフォルトの名無しさん
07/06/26 10:35:19
つーかC++の例外が糞で使いにくいだけ
79:デフォルトの名無しさん
07/06/26 10:35:24
例外は「うっかり無視」できないのがいいんだよ。
80:デフォルトの名無しさん
07/06/26 10:43:09
そうそう。
81:デフォルトの名無しさん
07/06/26 11:55:16
例外は戻り値と違って発生源や内容の概要が簡単に特定できるから
エラー→復旧っていう処理に使いやすい
エラーしたら即一連の処理を中断するだけなら戻り値でもいいけど
エラー内容によってstrategyパターンを使って処理を色々と変えるなら
例外の方がやりやすい
と思ったんだけどどうかな?
軽く試してみてちょっと良いかもって思っただけで使い続けられるとは限らないけど
82:デフォルトの名無しさん
07/06/26 14:05:12
std::fstream のコンストラクタに渡すファイル(パス)文字列って、
ネイティブなフォーマットのものなの?それとも POSIX
準拠じゃなきゃいけない?たとえば UNIX では /home/hoge/test.txt
で Windows では C:\home\hoge\test.txt ?
どういうフォーマットのパス文字列を取りうるかに関する
規約って定められてるの??
83:デフォルトの名無しさん
07/06/26 14:39:34
POSIX かんけーねー。
処理系で好きに決めりゃいいべさ。
84:デフォルトの名無しさん
07/06/26 14:48:09
そうか・・・標準の C++ のライブラリではそこまでは
決められていないんだね。 boost::filesystem では
native/ portable が厳密に切り分けられていたので、
fopen や fstream でもそうなってるのかと思った。
85:デフォルトの名無しさん
07/06/26 14:51:43
>>82
const char*なのが困り物
たとえばVC++8.0ではlocale依存の方法でUTF-16に変換する
それ以前ではコードページ依存の方法でUTF-16に変換する
いずれにせよ、NTFSのUTF-16なパスを正しく扱えるとは言いがたい
UTF-16なパス名をちゃんと扱いたければ、fstreamを捨てて
カスタムのストリームバッファを作れという話になるだろう
86:デフォルトの名無しさん
07/06/26 21:17:53
ofstreamやifstreamでファイルを開くとき、
ios::binary指定というのは、意味があるのでしょうか?
コンパイラはg++です。
いままでとくに指定してもしなくても結果は同じになりました。
87:デフォルトの名無しさん
07/06/26 21:23:21
>>86
UNIX系は関係ない。
WIndowsはstd::endlや\nを書き込むと0x0d0x0aになって書き込まれ
読むときは0x0d0aが0x0aになる。
88:デフォルトの名無しさん
07/06/26 21:26:02
ios::binaryしない奴は死ねっていつも思う。
89:デフォルトの名無しさん
07/06/26 21:27:15
>>86
テキストファイルを特別扱いする(というよりC++としては特別扱いしなければならない)環境も結構ある
有名どころではDOS/Windows系のテキストファイルでは改行コードがCR+LFになっていることが挙げられる
そういう環境では、テキストファイル特有の処理を行わせたくないときに、バイナリモードを指定する必要がある
逆にUnix関係では大抵違いがないが、移植性向上のために必要に応じバイナリモードを意識的に使うのは良いことだ
Unixとかでもワイド文字ストリームなら、文字コード変換をどうするかで
テキストモードとバイナリモードの違いが表れるはず
90:デフォルトの名無しさん
07/06/26 23:37:20
while(!feof(fp1)){
ch = fgetc(fp1)
if(!feof(fp1) fputc(ch,temp);
}
ファイルの中身を別のファイルにコピーする場合の例題に書かれていたコードなんですが
whileの式で(!feof(fp1))と記述されているにもかかわらず何故さらにif(!feof(fp1)と書いているのは何故なんでしょうか?
何か意味があるんですか?
whileの式でファイルの末端にきたらループ終了なのでifの式は必要ないように思えるんですが
91:デフォルトの名無しさん
07/06/26 23:44:12
>>90
意味以前にその例題、コンパイルできるか?
92:デフォルトの名無しさん
07/06/26 23:45:19
>>90
fgetc()で読みに行ってみないとEOFだとわからんことがあるから。
その場合、whileの条件式の時点ではEOFではないと判断して
読みに行ってみたらEOFだった(読めませんでした)というカタチになるので
下のチェックが要る。
だがこんなのは糞コード。
while ((ch = getc(fp)) != EOF) putc(ch, temp);
とするがよい。
93:デフォルトの名無しさん
07/06/27 00:12:20
>>92
バイナリファイルを操作する場合は>>90の方がよい
94:デフォルトの名無しさん
07/06/27 00:13:20
>>93
なぜ?
95:デフォルトの名無しさん
07/06/27 00:16:51
>>94
int型と比較した時、EOFと同じ値のバイトが存在する可能性があるから
96:デフォルトの名無しさん
07/06/27 00:17:02
とても初歩的な質問ですが
short i;
long k;
float f;
double d;
としたときに
① (f+15)/(long)(d-15)
② k+20.0
③ (int)d/i
の型(double,longなど…)はどうなるでしょうか?
こういう場合は計算式の中でもっとも高精度な変数の型になると理解すればいいのでしょうか?
97:デフォルトの名無しさん
07/06/27 00:17:55
>>95
あ、chがcharだと仮定しているわけね。
それならば、単にint chと宣言して>>92のコードで良い。
98:デフォルトの名無しさん
07/06/27 00:21:04
>>96
整数拡張、型の昇格
99:デフォルトの名無しさん
07/06/27 00:23:00
というかgetc()の戻り値をcharで受け取る奴がアホ
100:デフォルトの名無しさん
07/06/27 02:13:04
C++でのバイナリファイルの読み書きは、ifstreamのreadとか、ofstreamのwriteを使うんですよね。
気になったのは、どちらも char * を指定するところです。freadは void * だったと思うんですが。。。
ifs.read(reinterpret_cast<char *>(&hoge), sizeof(unsigned)); という感じで、毎回キャストしないといけないんですか?
101:デフォルトの名無しさん
07/06/27 02:27:57
>>100
残念ながらキャストが必要。
毎回キャストするのが嫌なら、適当な関数で包め。
102:デフォルトの名無しさん
07/06/27 04:13:44
別にfread使っても一向にかまわないわけだし。
適材適所。
103:デフォルトの名無しさん
07/06/27 09:36:59
freadはvoid*の代わりに、サイズと数の2つを指定するだろう
104:デフォルトの名無しさん
07/06/27 09:42:16
fread()/fwrite()は(Unixの)read()/write()のインタフェース
真似れば良かったのにな
105:デフォルトの名無しさん
07/06/27 10:16:53
データがBIG ENDIANかLITTLE ENDIANのどちらかで
単純に&hogeで受け取れない場合もあるし。
つまり、CPUとデータの並びが逆の場合。
今回みたいに並びが合ってるのなら、union使えばいいんじゃないか?
106:デフォルトの名無しさん
07/06/27 10:26:23
ネットワークを跨ぐとか、別PCでもそのファイルを r/w するのならエンディアン気にするけど…
たかだか、同じPC内で完結するのならそのまま保存するよね?
107:デフォルトの名無しさん
07/06/27 10:41:33
そりゃファイル仕様に因るべさ。
108:デフォルトの名無しさん
07/06/27 10:49:46
ああ、先にファイル仕様があって(当然エンディアンも明示されてて)それを
読む→(なんかする)→(書く) なら、それに従うしかないね。
109:デフォルトの名無しさん
07/06/27 12:14:06
>>87-89
なるほど、ではテキストでないときには、
ios::binaryを付けるようにします。
110:デフォルトの名無しさん
07/06/27 14:39:49
基底クラスのポインタを継承クラスの動的配列でオーバーライドすることはできませんか?
class Base{
public:
Base(){val0=0;};
virtual ~Base(){};
virtual void show(void){cout << val0 << endl;}
int val0;
};
class Deriv:public Base{
public:
Deriv(){val1 = 1;};
virtual ~Deriv(){};
virtual void show(void){cout << val1 << endl;}
int val1;
};
int main(int argc, char *argv[]) {
Base *test;
int num = 10;
test = new Deriv[num];
for(int i=0;i<num;i++)
test[i].show();
}
を実行すると,main()の中のfor文2回目のループ(i=1)で
0x0041e12c でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000005 を読み込み中にアクセス違反が発生しました。 。
というエラーが出ます。
test[0]は無事Derivにオーバーライドできていますが,test[1]以降が不可能なようです。
何か良い方法はないでしょうか?
環境:WindowsXP + VisualC++ Ver.7
111:110
07/06/27 15:02:56
オーバーライドの意味間違ってますね。
何と呼んで良いのか分からないですが、領域確保?
とにかくnewするという意味です。
112:デフォルトの名無しさん
07/06/27 15:11:45
>>110-111
BaseとDerivのメモリ上の大きさが違うのに、配列でどう動けと。
113:デフォルトの名無しさん
07/06/27 15:34:55
無理するなら↓
((Deriv *)((char *)test + sizeof(Deriv) * i))->show();
もしくは↓
((Deriv *)test)[i].show();
114:110
07/06/27 15:51:45
>>112,113
ありがとうございます。
なんとなく分かりました。
new Deriv[num]が失敗してるのではなく、
forループのなかでのindexの指定が間違ってるということですね。
*testがBase型のポインタなので
test[i]はtest[0]からBaseを基準にアドレスを進めることになるのか。
>>113さんの方法で動きましたけど、
そもそもこういう状況が必要になる設計はまずいでしょうか?
115:デフォルトの名無しさん
07/06/27 16:28:34
>>114
一般的にはまずい。
でも、テンプレートを使って下のようにやればできないことはない。
template<class T>
class poly_array {
template<class U>
poly_array(U *ptr, int array_size) : ptr_(ptr), size_(sizeof(U)) ... {...}
T *get(int i) {return (T *)((char *)ptr_ + size_ * i); }
private:
T *ptr_;
size_t ptr_size_;
...
};
116:デフォルトの名無しさん
07/06/27 16:34:21
基底クラスへのポインタの配列を作って、
それぞれに対してまたオブジェクトを作っていくのが、
まあ一番安全なのかね。
メモリ管理が複雑になるという点では、
安全とは言えんかもしれんが。
>>115 はちょっと感動したよ。
117:デフォルトの名無しさん
07/06/27 17:51:04
下記を左側の数字のキー値で、ソートしたいです。
(8,x),(2,y),(3,z)・・・
ソートして、
(2,y),(3,z),(8,x)・・・
を出力。(int,std::string)の形です。
どういうデータで扱って、どのような方法がよいでしょうか。
mapとか自動でソートされるみたいですが、
自分で比較して並べ替えたいです。
よろしくお願いします。
118:デフォルトの名無しさん
07/06/27 17:58:37
int, std::string をメンバに持つ構造体の配列?
それなら構造体で < 演算子をオーバーロードするか
比較関数を定義するかすれば
std::sort でソートできるけど。
119:デフォルトの名無しさん
07/06/27 18:00:21
>>117
つ[std::vector]
120:デフォルトの名無しさん
07/06/27 18:12:57
訂正お願いします。
×キー値で、ソート
○キーでソート
>>118
ごめんなさい。
「(int,std::string)」
これは、余計でした。(数字,文字列) なんです。
どのデータに入れて、どんな風に処理するのか知りたいです。
>>119
std::vectorに、キーを入れてソートするんでしょうか?
対応する値は、どうやって対応させて出力を。。。
121:デフォルトの名無しさん
07/06/27 18:19:20
何がしたいのかよく分からない。
int 値はキーで、std::string はキーに対応する値?
std::map を使うのがベストだと思うけど、
std::map を使わない理由は何かあるの?
122:デフォルトの名無しさん
07/06/27 18:22:08
>>117
とりあえず、すんごい単純で愚直な方法。
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
typedef std::pair<int,std::string> nspair;
bool cmp(const nspair& a, const nspair& b) { return a.first < b.first; }
int main()
{
int n;
std::string s;
std::vector<nspair> vec;
while (std::cin >> n >> s)
vec.push_back(nspair(n,s));
sort(vec.begin(), vec.end(), cmp);
for (std::vector<nspair>::iterator i = vec.begin(); i != vec.end(); ++i)
std::cout << '(' << i->first << ',' << i->second << ')' << std::endl;
}
123:デフォルトの名無しさん
07/06/27 18:25:51
>>116
つboost::ptr_vector
124:デフォルトの名無しさん
07/06/27 18:41:02
>>121
(数字,文字列),,,,
をキーでソートするんですが、どんなデータに格納して
どんな処理をするのか知りたかったんです。
>>122
プログラムも、書いていただきありがとうございます。
数分しかたってないのに。(汗
中身がstd::pairのstd::vectorですか。
typedefの使い方もすごい勉強になります。
ありがとうございました。
125:119
07/06/27 19:10:32
ちっ、プログラムを書いてみたけどstd::pairとstructの違いだけで殆ど同じだから貼るのやめよ。
126:デフォルトの名無しさん
07/06/27 21:01:34
>>124
(数字,文字列) 全体がキーなの?
じゃ、それに対応する値もあるの?
それとも set みたいにキー=値なの?
そして、数字が同じ時には文字列も比較するの?
と、質問攻めになってしまった。
127:デフォルトの名無しさん
07/06/27 21:30:26
結局ポインタって何に使うんですか?
違った名前の変数で同じ値を参照できるってことですか?
でも同じアドレスの値を参照するだけならわざわざポインタの方の変数を作る必要は無い気が・・・・
ていうかそもそもいろんなソースコードを見ててもポインタを使ってるのはあまり見かけませんが・・・・
128:デフォルトの名無しさん
07/06/27 21:32:29
>>127
C はポインタが無ければ配列も関数に渡せない言語です。
129:デフォルトの名無しさん
07/06/27 21:34:24
ポインタ使いまくりw
ポインタを理解していないみたいだが君も知らない内に使ってるよ
130:デフォルトの名無しさん
07/06/27 22:04:33
>>127
scanfを使ったことはないのかい?
131:デフォルトの名無しさん
07/06/27 22:08:35
ポインタより似たような文法上の特徴を持つC++のイテレータの方から覚えた方がいいかもね
概念としては似たようなもんだし、イテレータ理解できるならポインタも理解できるようになるか
どうしてもポインタが駄目ならC++でイテレータから入るのも十分ありだよ
132:デフォルトの名無しさん
07/06/27 22:54:19
ポインタの概念を理解できないレベルでイテレータを理解できるか疑問
133:デフォルトの名無しさん
07/06/27 23:05:18
イテレータ自体がデータをポインタライクに扱うようなもんだしなぁ
134:デフォルトの名無しさん
07/06/27 23:08:52
ポインタのノリでイテレータが使うとそれはそれでバグの元に・・・
135:デフォルトの名無しさん
07/06/27 23:10:27
アドレスがどうのという話が無いぶんイテレータの方が簡単だと思うな
概念的な話より、何が出来るかの方が理解しやすいだろう
136:デフォルトの名無しさん
07/06/27 23:25:39
抽象概念を理解できない香具師にはどっちみち理解できない罠。
137:デフォルトの名無しさん
07/06/28 00:07:25
ポインタがわからない→Javaへ行く
Javaのダメプログラマがまた一人。
138:デフォルトの名無しさん
07/06/28 00:17:46
>>127
a = 5; /* aに対応する箱に5を入れる */
b = a; /* bに対応する箱に、aに対応する箱から取り出した値を入れる */
おんなじaでも式の右辺と左辺ではぜんぜん意味が違うのだが、それを理解してるかな?
物を入れるには箱が必要で、Cで箱そのものを値として取り回すための
仕掛けがポインタだ。
どういう時に必要になるかはいずれ分かる。
139:デフォルトの名無しさん
07/06/28 00:47:44
Cでのポインタの必要性が特に大きいのは、配列や左辺値を渡す手段が
他に存在しないから。関数は全部値渡しだし。
参照渡しが存在するならポインタの必要性は大分減るが、リストや木のような
配列より複雑なデータ構造を扱うようになれば、ポインタの有用性が自然に
理解できるだろう。
140:デフォルトの名無しさん
07/06/28 01:14:41
>>127
関数とのデータ受け渡し時に構造体とかそのまま実体渡すとコピーされるのでメモリの無駄だし速度的にもデメリットがある
それに不定なサイズのデータを扱おうと思ったらポインタ使うと思うが。
141:デフォルトの名無しさん
07/06/28 14:42:29
vc++2005で警告レベルを/W4にした時、
stlのアルゴリズム使って代入処理とかイテレータを用いたコンテナの初期化とかすると
> xutility(1685) : warning C4244: '+=' : '__int64' から '__w64 unsigned int' への変換です。
> データが失われる可能性があります。
とかコンパイラ様が仰られて出力窓がカオスになって困るのでこれをどうにかしたい訳ですが
こういうのは#includeディレクティブの羅列全体に(つまりxutilityを使ってるライブラリ全体を)
#pragma warning(disable:4244)と
#pragma warning(default:4244)やpush, pop使って抑制を適用しちゃっていいんでしょうか?
一応、ライブラリ以外の部分ではちゃんと/W4で警告が行われますし問題ないと思うんですが
なんか良い解決法ってございませんかね?
142:デフォルトの名無しさん
07/06/28 14:47:55
>>141
__w64 は 64 ビットにするんじゃなくて、
32 ビット環境でコンパイルする時にも
もし 64 ビットにしたとしても整合性が取れるかチェックするだけ。
つまり、__w64 unsigned int は 32 ビット環境では 32 ビット符号無し整数型になる。
__int64 は 64 ビット符号付き整数型だから、
そこから 32 ビット符号無し整数型への暗黙変換で警告が出るのは当たり前。
それで本当に大丈夫なのかをまず確認した方がいい。
143:デフォルトの名無しさん
07/06/28 14:53:54
boost::serialization ってクロスプラットフォームで
使ってもおk?つまりできたファイルはプラットフォームを
またいで移動してもおk?たとえば endian の異なる
プラットフォームに持っていっても安全?
144:デフォルトの名無しさん
07/06/28 15:32:13
>>142
なるほど、助言をヒントに
使用するされているイテレータの差の型にsize_tを指定して定義すればあっさりと消えました
どうもです><
145:デフォルトの名無しさん
07/06/28 17:04:11
>>144
> イテレータの差の型
difference_typeのことならstd::size_tよりも
符号付のstd::ptrdiff_tのほうがいい。
it = begin();
it2 = begin();
++it2;
このときit2 - itは1になるはずで、it - it2は-1になるべきだから。
146:デフォルトの名無しさん
07/06/28 17:25:10
>>143
あれの出力形式にはいろいろあって、
バイナリは知らないけど、xmlなら間違いなくできる。
147:デフォルトの名無しさん
07/06/28 17:51:43
API の話ではないが、質問していいですか。
_tprintf(_T("あいう"));
とするとコンソールに正常に表示されないのですが、
どのようにしたら正常に表示できるでしょうか?
148:デフォルトの名無しさん
07/06/28 18:00:43
setlocale(LC_ALL, ""); でできた。
149:デフォルトの名無しさん
07/06/28 22:02:18
イテレータの差ならiterator_traits<hoge_iterator>::difference_typeだろ。
150:デフォルトの名無しさん
07/06/28 23:31:40
板違いで流れてきましたw
01011010みたいに
日付が4桁4桁になってる
8桁の数字一覧の出力方法教えてください
151:デフォルトの名無しさん
07/06/29 00:53:49
>>128-140
関数内で宣言した変数はほかへは渡せないから、同じ中身を参照できるポインタを使って
ほかの関数内でも関数内で変更した変数を渡せるようにするのがポインタですか?
自分で書いててわけがわからない文だな・・・・
とりあえずまだまだ自分は未熟なのがわかったのでまた最初から勉強しなおします!
152:デフォルトの名無しさん
07/06/29 07:50:22
>>150
それは、西暦101年10月10日か、01年1月10日10時なのか、1月1日10時10分なのか、101日目、10時10分なのか、
或いはそれ以外の表現なの?
そもそも一覧とはなんなの?
153:デフォルトの名無しさん
07/06/29 09:46:27
お客様の中にESP能力者の方は・・
154:デフォルトの名無しさん
07/06/29 09:48:43
%04d%02d%02d
155:デフォルトの名無しさん
07/06/29 13:59:10
同じ内容の関数を、マルチスレッドで動かして
ログファイルに処理内容を、追加書き込みで
書き出してます。
std::ofstream ofs( FileName.c_str(), std::ios::out|std::ios::app);
ofs << message;
結構、同じタイミングで書き込むときあると思うのですが、
排他処理したほうがいいでしょうか?
そもそも"ファイルが壊れる"っていうのは、どんな壊れ方があるのでしょうか?
真っ白になっちゃうのか、混ぜこぜで書き込みされる。などですか?
156:デフォルトの名無しさん
07/06/29 14:04:07
>>155
混ざります。しかも、通常バッファリングされるので行の途中でもお構いなしに混ざることになります。
運が悪いと、書き込んだ筈の分がロストしたり以前の分がロストしたりするかもしれません。
157:デフォルトの名無しさん
07/06/29 14:06:54
俺の認識な。
ファイルが壊れる = ファイルアクセスに失敗してしまう。 居るように見えて実体が居なかったりする等
マルチスレッドのロギングで、同期取ってない場合
出力が途中で差し込まれたようなデータ列になる等、意図してないフォーマットで出力されてしまう
158:デフォルトの名無しさん
07/06/29 14:07:57
>>156
混ざるのは、構わないと思ってたのですが
無くなるときもあるんですか。
じゃあ、ファイルロックとかで、ロックするようにします。
ありがとうございました。
159:デフォルトの名無しさん
07/06/29 14:09:19
>>157
ふむふむです。勉強になります。
ありがとうございます。
160:デフォルトの名無しさん
07/06/29 14:12:02
>>157
もみもみです。あぁ~ん♪
感じちゃう?
161:デフォルトの名無しさん
07/06/29 14:24:45
>>155
使っているlibc++がマルチスレッド対応してるなら(今時なら普通してると思うが)
istream/ostreamの関数呼び出しの単位で排他してくれてるはずだ。
つまり、例えばあるスレッドでoperator<<()が呼ばれた場合、その間は
streambufがロックされるので、streambufの内部状態が壊されることが無い。
ヘルプなどのドキュメントに明記されていないなら、ソースを読むんだね。
ただ、排他はあくまで関数呼び出し単位なので、例えば
ofs << n << ":" << s << endl;
のようなことをやっているコードでは、operator<<()が4回呼ばれている間に
他のスレッドからの出力が割り込む可能性は当然あって、その場合は
出力がぐじゃぐじゃになる。
それを避けたければ、常に1行単位で出力関数を呼ぶようにするとよいだろう。
無論自前で排他をするという手もあるが。
162:デフォルトの名無しさん
07/06/29 14:25:36
バッファリングはどーなのよ
163:デフォルトの名無しさん
07/06/29 14:28:01
>>162
バッファリングを管理しているのはstreambufで、これがstdioのFILEの対応物。
i/ostreamはstreambufへのポインタを保持しており、排他はstreambuf自体を
ロックするような形でやっていることが多いはずだ。
つかソース嫁よ。
164:デフォルトの名無しさん
07/06/29 14:31:06
結局スレッドセーフなカスタムストリームを実装するしか無いなね…orz
165:デフォルトの名無しさん
07/06/29 14:35:55
無いなね
166:デフォルトの名無しさん
07/06/29 14:36:41
OTL
167:デフォルトの名無しさん
07/06/29 14:51:26
>>163
別に聞いたわけじゃない。
>>161のように排他してもバッファリングしてたら意味無いだろ、と
168:デフォルトの名無しさん
07/06/29 14:56:17
アンダーバーで始まる関数
_stprintf_s みたいにアンダーバーで始まる関数があるのですが、
アンダーバーで始まる関数には何がしの意味があってアンダーバーをつけてるのですか?
たとえば、MSによって拡張されたことを示すために付けられたとか
169:デフォルトの名無しさん
07/06/29 14:59:44
バッファへの操作込みで排他処理されてるんじゃないのか?
170:デフォルトの名無しさん
07/06/29 15:03:59
>>168
URLリンク(www.microsoft.com)
171:デフォルトの名無しさん
07/06/29 15:05:18
って前の _ か
標準じゃないやつにつけるべ
172:デフォルトの名無しさん
07/06/29 15:07:11
MS は独自の拡張関数に _ つけるよね。
173:デフォルトの名無しさん
07/06/29 15:16:35
>>168
アンダーバーから始まる名前は処理系のために予約されている
と規格で決められている
174:デフォルトの名無しさん
07/06/29 15:25:35
>>169
バッファリングされる場合、実際にファイルに書き出されるのはどのタイミングか判って言ってる?
175:デフォルトの名無しさん
07/06/29 15:31:43
それが何か関係あるの?
176:デフォルトの名無しさん
07/06/29 15:33:57
バッファ単位での実書き出し最中に、別スレッド側のバッファ操作はどうなるか
177:デフォルトの名無しさん
07/06/29 15:37:59
失敗するー
だから入出力関数の戻り値は常にチェックしてけって話ですか?
178:デフォルトの名無しさん
07/06/29 15:39:21
同じバッファ使って操作するわけじゃなくて、
別々のバッファで操作しようとしてるの?
179:デフォルトの名無しさん
07/06/29 15:47:23
そりゃ別スレッドなんだからバッファは違うだろう
180:デフォルトの名無しさん
07/06/29 15:49:43
同じファイルに追記するだけなら、
別スレッドで同じオブジェクトを共有して
操作したんでいいんじゃないの?
181:デフォルトの名無しさん
07/06/29 15:58:37
OS管理下のファイル本体
↑↓
OS管理下のバッファ
↑↓
ライブラリ管理下のバッファ
なんとなくライブラリ管理下のバッファの排他がかかってればうまくいきそうだが…
182:デフォルトの名無しさん
07/06/29 16:00:15
スレッドセーフ版のライブラリを名乗るからには
そうなってんじゃないの?
183:デフォルトの名無しさん
07/06/29 16:59:25
>>167
バッファリングされていようが、何の問題もないよ。
脳内の想像でいい加減なことを言っていないで、ソースを読むかせめて
実験したらどう?
184:デフォルトの名無しさん
07/06/29 17:18:33
>>172
_snprintf() と snprintf() の挙動の違いにしょんぼりした。
185:デフォルトの名無しさん
07/06/29 17:24:42
今のgnustdc++ってMT safeなんかな?
VC++だと、basic_ostream<>::sentryを利用して排他制御をやってるんだが、
3.4.4ぐらいのgccだと、何もやってないように見えるな。
186:デフォルトの名無しさん
07/06/29 17:29:58
もしかして>>167は、同じostreamオブジェクトに複数スレッドから
書き込むのではなく、
同じファイルに複数スレッドから別々のostreamオブジェクト経由で書き込むという
状況を想定してたのか?
無論、その場合はostream内部で排他制御しても何の意味も無いぞ。
187:デフォルトの名無しさん
07/06/29 17:34:42
>>186
>同じファイルに複数スレッドから別々のostreamオブジェクト経由で書き込む
こっちのほうが複雑な排他制御になりそうだな…
188:デフォルトの名無しさん
07/06/29 17:49:39
ログ出力のように行レベルではアトミックであって欲しい&必ず追加書きって
ケースを想定するなら、
例えばUnixだと、O_APPENDでopen()してwrite()一発で1行を書き込むように
している限りは、マルチスレッドだろうがマルチプロセスだろうが、
何の排他制御も要らない。
189:デフォルトの名無しさん
07/06/29 20:46:52
Visual C++ 2005を使用しています。
xmlの書式で書かれたデータがint型の配列に入っているとします。
その配列から、xmlのあるタグ(例えば<script>という文字列)が
あるかどうかを検索したいと思います。
この場合、どのような方法がお勧め(簡単な実装、早い検索)でしょうか?
以下のいずれかを考えていますが、どうでしょうか?
(1) memcmp()を使いながら、<Script>に対応する数字を探していく
(2) string型に変更し、string.find()で探す
そのほかにお勧めの方法はあるならご教授願います。
(2)をすべきなら、どのようにint→stringに変換するのでしょうか?atoiを使うので
しょうか?
190:デフォルトの名無しさん
07/06/29 20:49:38
> xmlの書式で書かれたデータがint型の配列に入っているとします。
ここから既にイミワカンネェ
191:デフォルトの名無しさん
07/06/29 20:56:43
どうやって読み出してきたら、int型配列になるんだ?
ひょっとして、UCS4なのか?
192:デフォルトの名無しさん
07/06/29 21:05:29
xml形式のデータがint型の配列に返ってくるメソッドがあるのです。
void method(int *value)
というメソッドを使うと、valueの中にxmlが返ってくるケースがあります。
xmlデータじゃないのも返ってくるのでint の配列で返ってくるのだと
思います。
すいませんが、教えていただけないでしょうか?
193:デフォルトの名無しさん
07/06/29 21:12:22
エスパー募集中☆
194:デフォルトの名無しさん
07/06/29 21:16:38
intにどうやってxmlを入れるんだ?
195:デフォルトの名無しさん
07/06/29 21:20:22
>>192
だから、その int 配列の中にどういう形式で文字列が入ってるんだ? と。
>>191の言うように UNICODE (しかも32ビットの UCS4)なのか。
コード体系によってその "<script>" だって表現の方法が変わってしまうから、
そこが分からなければ意味がないし(というかそれこそがこの問題の本質)、
そこを君が述べていないので「ESP」とか言われてしまうのだよ、と。
196:デフォルトの名無しさん
07/06/29 21:20:27
無理矢理入れます。処女マンコ犯すように
197:デフォルトの名無しさん
07/06/29 21:21:27
>>195
xmlで入ってます。
198:デフォルトの名無しさん
07/06/29 21:22:01
xmlを扱うなら専用ライブラリ使う、もしくは作るべし
199:デフォルトの名無しさん
07/06/29 21:22:18
ご返信ありがとうございます。
"<?xml" だったら "60 63 120 109 108"とそれぞれの値が
int型の配列に入っております。
String型でデータをもらえればいいのですが、メソッドの仕様の
関係上、int配列でしか受け取れません。
200:デフォルトの名無しさん
07/06/29 21:22:34
もはや釣りにしか見えん
201:デフォルトの名無しさん
07/06/29 21:22:57
なんで言葉で説明しようとするのかね。
データをそのまま貼り付ければいいのに。
202:デフォルトの名無しさん
07/06/29 21:23:48
とりあえず文字列形式に変換してから、
ライブラリ通して解析すべき
203:199
07/06/29 21:23:59
Asciiコードで入っております。
みなさんを混乱させる状況にしてしまってすいません。
204:デフォルトの名無しさん
07/06/29 21:24:23
>>199
漢字が入ってる場合はどういう具合に返ってくる?
205:デフォルトの名無しさん
07/06/29 21:24:42
文字化けして返ってきます。
206:デフォルトの名無しさん
07/06/29 21:25:03
>>205
文字化けじゃわからんから、実例で示せ
207:デフォルトの名無しさん
07/06/29 21:27:33
ってか、漢字ってこの話で関係あるのか?
208:199
07/06/29 21:27:41
返ってくるデータに漢字は含まれないのでわかりません・・・
みなさんを怒らせてしまってすいません。int→stringの文字列
変換を行うことを考えて実装してみます。
本当にすいませんでした。
209:デフォルトの名無しさん
07/06/29 21:28:29
失礼しちゃうわ!
210:デフォルトの名無しさん
07/06/29 21:29:20
>>207
エンコーディングを判別したかったんだが。
XMLライブラリを使うんなら必要なことだろ。
211:デフォルトの名無しさん
07/06/29 21:30:10
asciiって言ってるじゃん。
212:デフォルトの名無しさん
07/06/29 21:31:09
>>211
漢字は文字化けするとも言ってるが。
213:デフォルトの名無しさん
07/06/29 21:32:17
まあ本人がもういいつってんだからどうでもいいやな。
214:デフォルトの名無しさん
07/06/29 21:32:20
>>212
だから、Asciiだから漢字は含まれていないし、
含まれていたらどうなるか分かりませんって言ってるんでしょ。
215:デフォルトの名無しさん
07/06/29 21:32:33
VCのデバッガで見て言ってたんじゃないかな
216:199
07/06/29 21:35:06
たびたび出てきてすいません。
205は私は書いておりません。ASCII文字です。
215さんのおっしゃるとおり、デバッグで確認して
回答していました。
217:デフォルトの名無しさん
07/06/29 21:35:45
失礼しちゃうわ!
218:デフォルトの名無しさん
07/06/29 21:38:01
191が指摘しているとおりなのだが、
intが4バイトならUTF-32、2バイトならUTF-16と見なして構わないはず。
そのまま適当なXMLのライブラリへ投げてしまえ。
219:デフォルトの名無しさん
07/06/29 21:38:19
> xml形式のデータがint型の配列に返ってくるメソッドがあるのです。
> "<?xml" だったら "60 63 120 109 108"とそれぞれの値が
> int型の配列に入っております。
もしかして、単にテキストファイルを読み込んで各文字(ASCII)のコードを
int型の配列に格納しているだけ?
1行ずつとか、ファイル全体とか。XMLの構造に関係なく。
220:デフォルトの名無しさん
07/06/29 21:38:29
質問です。
配列の要素数をキーボードからの入力によって定めさせたい場合、どのような方法があるでしょうか。
int n;
int a[n];
という宣言だとa[n]の宣言がエラーになってしまい、scanfによってnの値を決定した後にa[n]を宣言してみてもやはり「そこで宣言は出来ない」とエラーになってしまいます。
どなたかよろしくお願いします。
221:デフォルトの名無しさん
07/06/29 21:40:02
int *a;
nを読み込む。
a = (int*)malloc(sizeof(int)*n);
222:199
07/06/29 21:42:18
219さんのおっしゃる通りでした。xmlなどの概念を理解せずに
使用してしまって混乱を招いてしまったようです。
>もしかして、単にテキストファイルを読み込んで各文字(ASCII)のコードを
>int型の配列に格納しているだけ?
>1行ずつとか、ファイル全体とか。XMLの構造に関係なく。
この場合、XMLのライブラリを使えるのでしょうか?
223:デフォルトの名無しさん
07/06/29 21:42:21
>>220
CかC++か、どっちだい
Cならmalloc/freeで検索
C++ならnew/deleteで検索、もしくはstd::vectorで検索
でもそのレベルだとnを十分大きく取るって解決策の方が
いいかもしれない
224:デフォルトの名無しさん
07/06/29 21:45:24
>>222
もし非ASCII文字が入っていないなら、>>219の言うとおりにやればいい。
と言いたい所だが、sizeof(wchar_t) != sizeof(int)のときに、
int配列をそのまま処理してくれるXMLライブラリってあるのかな。
俺は知らない。
ただ、非ASCII文字が無いのなら、stringなりchar配列に変換するのは
難しいことでも何でもない。受け取ったint配列の値をそのまま
突っ込んでいくだけだからな。
225:デフォルトの名無しさん
07/06/29 21:45:58
>>199
とりあえずXMLのライブラリを探してきて、その仕様を調べること。
仕様を見て理解できないようなら、まずはC言語の基本とかXMLについてもっと勉強すること。
226:199
07/06/29 21:47:54
みなさん、本当にありがとうございました
(1) XMLのライブラリを調べる、勉強する
(2) int型配列をStringに変換することを考える
で、がんばってみたいと思います。ありがとうございました。
227:デフォルトの名無しさん
07/06/29 21:49:54
100年後にまた会えるといいな
228:デフォルトの名無しさん
07/06/29 21:50:56
真面目にやれば数日後だと思うけど、まあ頑張れ
229:デフォルトの名無しさん
07/06/29 22:01:06
ところでさっきからStringといっているのが気になるが、
もしかして.NET FrameworkのSystem.Stringのことか?
それならUnmanagedMemoryStream + StreamReader + UTF32Encoding
必要ならそれにXmlTextReaderでいいような気がする。
230:デフォルトの名無しさん
07/06/29 22:04:48
>>168 です。
お前ら、ありがトン。
アンダーバーで始まる関数:
アンダーバーから始まる名前は処理系のために予約されている。
そして、これを利用してMS は独自の拡張関数の名前の最初に_ つけている。
ということだな。
231:デフォルトの名無しさん
07/06/29 22:06:12
違うよ?
232:デフォルトの名無しさん
07/06/29 22:14:24
>>231
230でないけど何が違うか教えてください
233:デフォルトの名無しさん
07/06/30 00:58:49
>ということだな。
違うよ?
234:デフォルトの名無しさん
07/06/30 04:16:48
「処理系のために」ではないだろ。
235:デフォルトの名無しさん
07/06/30 07:22:32
ハード的なクリックでは無くソフト側で移動・クリック・入力の繰り返しをさせるプログラムを作りたいのですが
MSDNの見方がよく分からなくてmouse_eventを使うかもしれないという程度しかわかりませんでした・・・
使えるAPI・サンプルなどがあったら教えてください
よろしくお願いします
236:デフォルトの名無しさん
07/06/30 08:39:51
SendInput
237:デフォルトの名無しさん
07/06/30 09:01:14
質問です!!
C言語のボーランドでコンパイルしたら元のメモ帳と、コンパイル後のファイルとって感じでいくつか手元にファイルできますよね。
そのとき作ったメモ帳が消えてしまったのですが(プログラムの実行はできる状態)。
コンパイル後のファイルからもとのメモ帳ってもう見ることができないのでしょうか・・・?
わかる方よろしくお願いします。
238:デフォルトの名無しさん
07/06/30 09:02:16
メモ帳って何だ?
239:デフォルトの名無しさん
07/06/30 09:03:12
んと、メモ帳にmainやらintやら打ち込んで、ボーランドでコンパイルしてコマンドプロンプトで実行って形でやってます。
そのとき書き込んだメモ帳です。
240:デフォルトの名無しさん
07/06/30 09:11:39
先ず最初に、「メモ(すなわちファイル)」と「メモ帳(アプリ)」を区別するところからはじめる必要がありそうだ。
で、あんたはその「メモ」をなんて名前で保存したんだ? そいつはコマンドプロンプトでdirしても見えないのかい?
241:デフォルトの名無しさん
07/06/30 09:15:54
dir でも見えないし、元の場所からは特に動かしてないので・・・
お恥ずかしながら消しちゃったみたいなんです・・・・
コンパイルの逆、みたいなことってできないのでしょうか?
242:デフォルトの名無しさん
07/06/30 09:22:53
>>241
それは無理。
243:デフォルトの名無しさん
07/06/30 09:23:43
う・・・・orz
ありがとうございました。
244:デフォルトの名無しさん
07/06/30 11:32:14
>>234
>17.4.3.1.2
>Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
implementationだから処理系でいいんじゃない?
JISの方も処理系て訳されてるし。
245:デフォルトの名無しさん
07/06/30 11:37:12
一応逆コンパイラはあるけど、
元のコードがそのまま出てくるわけじゃないからなあ。
246:デフォルトの名無しさん
07/06/30 11:46:10
デコンパイラでぐぐれ
247:デフォルトの名無しさん
07/06/30 18:46:38
スレッドで、複数の引数を受け取りたいとき、
std::vector<std::string>で渡したいと思ってます。
//スレッド関数
void Thread(void* vector){
std::vector<std::string> *vec=(std::vector<std::string>*)vector; //エラーでません。正しい?
vec->clear(); //コンパイルできても、例外がどうのと出て止まります。vec.clear()のつもりです
printf("%d",*vec[0].c_str()); //これだめです
}
○vectorの関数push_buck(),insert(),clear()など、使用したり、
vec[0]、、、の中の値が知りたいのですが、方法ありますでしょうか。
○vec.clear()とかしたいので、左辺にvecのままにして、いろいろ試しました。
std::vector<std::string> vec=(std::vector<std::string>)vector;
これは、コンパイルできませんでした。右辺がおかしいみたいです。どうすれば。。。
----------------------------------------------------------------
○構造体の場合:
vectorがstd::vectorではなく、自分で作った構造体の場合は、
Data *data = (Data *)vector;
data->hoge;
の要領で、できました。
よろしくお願いします。
248:デフォルトの名無しさん
07/06/30 18:53:01
>>247
たぶんスレッドに引数渡してるところがおかしい。
249:デフォルトの名無しさん
07/06/30 18:54:17
>>247
・C言語の形式のキャストではなく、C++のキャストを使ったほうがいい。
・コール元からThread()に渡したstd::vector<std::string>オブジェクトの寿命は大丈夫?
・vec[0]を見たいなら、std::cout << vec[0]; で良いんじゃない?
250:デフォルトの名無しさん
07/06/30 19:08:19
>>248
複数渡したいとき、構造体か配列などなどとあったので。。。
正直よくわからないです。すみません。
>>249
・C++のキャスト検索してみます。
・std::vector<std::string>オブジェクトの寿命ですか、
良く、無いものを参照して、プログラム止まります。
同じ症状なので、これかもしれません!
・vec[0]で、大丈夫ですか。了解しました。
ありがとうございました。
251:デフォルトの名無しさん
07/06/30 19:54:57
>>250
>>249が指摘してるが、多分スタック上に確保したvectorのアドレスそのまま
渡してるだろ。それじゃクラッシュするのは当たり前だ。
252:デフォルトの名無しさん
07/06/30 19:56:01
>>250
ごめん、まちがえた。
× vec[0]
○ (*vec)[0]
253:デフォルトの名無しさん
07/06/30 20:32:10
//void* のポインタキャスト行ったりきたり実験
std::vector<std::string> vec2;
vec2.push_back("hoge" );
void *vo=(void *)&vec2; //void*型、準備OK
//ここから、スレッドの関数で受け取ってから、std::vector<std::string>に戻す。
std::vector<std::string> *vec=(std::vector<std::string> *)vo;//キャストしました。
std::vector<std::string> vec3=*vec;
cout << vec3[0].c_str()<< endl;
cout << (*vec)[0].c_str()<< endl;//おまけ。std::vector<std::string>にしなくても、これでもいい。
これは、正常に動きました。キャストの仕方とか大丈夫みたいなので、
参照しようと思ったデータが無いみたいです。
>>251
>多分スタック上に確保したvectorのアドレスそのまま
>渡してるだろ。それじゃクラッシュするのは当たり前だ。
スタック?検索すると、
”処理中のデータや戻りアドレスなどを一時的に退避する場合に使うことが多い”
ってありました。
vectorは使用しなくなると自動的に、
開放しちゃうっていう、あれのことでよかったでしょうか?
254:デフォルトの名無しさん
07/06/30 20:38:10
なぜ新訂版More Effcitive C++の訳本は糞なのでしょうか?
255:247
07/06/30 20:39:16
vector、map、pairなど、いろいろあると思いますが、
こういうの使いたいときは、どうすればよいでしょうか?
自動で開放してくれなくても、いいので
構造体使うのが、わかりやすいですか。
256:デフォルトの名無しさん
07/06/30 20:42:28
>>253
> vectorは使用しなくなると自動的に、
> 開放しちゃうっていう、あれのことでよかったでしょうか?
ほんとに意味を分かって言ってる?
Javaなどのガベージコレクションと勘違いしないか?
ここで問題にしてるのは、C/C++で関数(またはブロック)内で宣言した変数は
その関数(またはブロック)を抜けると破棄されるということ。
いつの間にか勝手に消えるわけじゃない。
257:デフォルトの名無しさん
07/06/30 20:51:30
使用しなくなったら開放、って理解でいいと思うよ。
考えるな感じるんだ。
258:デフォルトの名無しさん
07/06/30 20:57:05
>>255
vector, map, pairなどはそれぞれ特徴が異なる。
データ同士の意味的なつながりとか、検索/更新の方法や性能など。
複雑なデータの管理をするときに、その使用方法にあったデータ構造を選択すればいい。
単にいくつかの型が異なるデータをひとまとめにして扱いたいだけなら
構造体でいい。
259:デフォルトの名無しさん
07/06/30 20:57:17
あぁ~ん!感じちゃう♪
260:247
07/06/30 21:12:13
>>256
詳しい解説ありがとうございます。
>>257
どもです。^^
>>259
261:デフォルトの名無しさん
07/07/01 03:24:35
何を突っ込もうとしてたんだ、>290にw
262:247
07/07/01 06:54:52
>>258
255って、自分でした。
構造体でよかったですか。ありがとうございます。
263:デフォルトの名無しさん
07/07/01 10:16:49
template<class T> inline void ZeroMem(T& dest) {
memset(&dest, 0x00, sizeof(T));
};
っていうのを作ったんですがこれって危険でしょうか?
264:デフォルトの名無しさん
07/07/01 10:18:02
めっちゃ危険
265:263
07/07/01 10:19:58
用途はwinapiで使う構造体の初期化です
一応実際のものは、POD以外渡すとコンパイルエラーになるようにboost::type_traitsとか作って
細工してあります
266:デフォルトの名無しさん
07/07/01 10:30:09
>>265
クラスの中に、newなどで確保済みポインタがあったらどうするんだい?
267:デフォルトの名無しさん
07/07/01 10:36:33
それはそういうのを渡さないように気をつけるとしか。。。
でもそんな事いったらmemsetも使えませんし
MSG msg;
msg.hwnd = 0;
msg.wParam = 0;
とか打っていくのが面倒なんで考えたので
初期化済みかどうかを判別する方法があればいいのですが
268:デフォルトの名無しさん
07/07/01 10:39:35
>>267
MSG msg = {0}; // 全部 0 で初期化
msg = MSG(); // 全部 0 を代入
269:デフォルトの名無しさん
07/07/01 10:42:44
そういう手があったんですね、トンクスです
270:デフォルトの名無しさん
07/07/01 10:44:03
何がトンクスど、トランクスか
271:デフォルトの名無しさん
07/07/01 10:44:04
こんなことも知らない奴がboost::type_traitsとか使ってんの蚊
釣りかと思った
272:デフォルトの名無しさん
07/07/01 10:56:34
一年ほど前に使った記憶はありますが
boostやpstadeと格闘している間、
構造体の初期化なんて殆ど使わなかったので忘れていました
ま、実質知らないのと同じですね^^^;
273:デフォルトの名無しさん
07/07/01 10:58:34
^^^何だこれは3つ目小僧か
274:デフォルトの名無しさん
07/07/01 12:48:20
どうしてC++にはコンストラクタとデストラクタがあって
デコンストラクタはないのなぜ?
275:デフォルトの名無しさん
07/07/01 12:53:36
>>274
デコンストラクタって何ですか?デストラクタと同じものではないですか?
276:デフォルトの名無しさん
07/07/01 12:53:41
Con structor
De structor
277:デフォルトの名無しさん
07/07/01 12:53:49
con-struct-erとde-struct-erだから
説明になっていないけど
278:デフォルトの名無しさん
07/07/01 12:53:51
デコンストラクタ = デストラクタ って考えちゃダメなの?
名前が違うだけやん
279:デフォルトの名無しさん
07/07/01 12:55:19
15秒で4レスついてるw
280:デフォルトの名無しさん
07/07/01 13:00:42
すみません
int a[] = new int[10];
int *b = new int[10];
みたいに確保したときって
delete a;
delete a[];
delete b;
delete b[];
それぞれ解放の仕方で動作おかしくなりますか?
281:デフォルトの名無しさん
07/07/01 13:06:03
delete a; アウト
delete a[]; アウト
delete b; アウト
delete b[]; アウト
282:デフォルトの名無しさん
07/07/01 13:08:16
これもアウトだ。
int a[] = new int[10];
283:デフォルトの名無しさん
07/07/01 13:08:56
>>275
デコンストラクタは脱構築です
ただの破壊ではありません
ポストモダンなのです
たぶん
284:デフォルトの名無しさん
07/07/01 13:09:01
>>274
「デコンストラクタ」はただの誤用だろ。
と思ったらこんなところにも。
URLリンク(msdn2.microsoft.com)(vs.80).aspx
原文はちゃんと destructor なのにね。
URLリンク(msdn2.microsoft.com)(vs.80).aspx
いちおう deconstruct という言葉も存在するらしい。
URLリンク(ja.wikipedia.org)
285:デフォルトの名無しさん
07/07/01 13:09:57
>>280 自分で試してから聞けよカス
286:デフォルトの名無しさん
07/07/01 13:38:11
>>285
それは禁句だよ。
new[]してdeleteのような正しくないのに環境によっては動くものを
正しい方法だと思ってしまう可能性がある。
287:デフォルトの名無しさん
07/07/01 13:40:29
配列のnew deleteは
T* v = new T[n];
delete [] v;
でおkなはず
288:デフォルトの名無しさん
07/07/01 13:46:31
いやここでstd::vectorとか言い出してやる。
289:デフォルトの名無しさん
07/07/01 13:48:11
valarrayの事も時々でいいから思い出してあげてください
290:デフォルトの名無しさん
07/07/01 13:49:43
>>286
今回はそれ以前の話。コンパイルできないのがダメ。
291:デフォルトの名無しさん
07/07/01 13:50:45
shared_arrayでいいんジャマイカ
292:デフォルトの名無しさん
07/07/01 14:00:49
いつものパターン:
書く → ビルド → エラーの数が100を超え(ry → (´・ω・`) → 少しずつ直していく
→ コンパイラ通過 → \(^o^)/ →実行時エラー → /(^o^)\ナンテコッタイ
293:デフォルトの名無しさん
07/07/01 14:03:35
delete b;
は正常に動作する。
今回に限ってはメモリリークを起こさない。
ただ、b[1]~b[9]のデストラクタが呼び出されないので、
プリミティブ型以外では動作保証ができない。
いかなる場合においても、new[]で確保したら、かならずdelete[]で解放すること。
だったっけ?
294:デフォルトの名無しさん
07/07/01 14:10:41
>>291
たまにはscoped_arrayのことも思い出してあげてください……。
295:デフォルトの名無しさん
07/07/01 14:15:44
>>293
いや違う。
未定義動作でFA。
296:デフォルトの名無しさん
07/07/01 14:29:41
>>293
デストラクタがあったらメモリの開放に失敗して落ちる環境がほとんど。
297:デフォルトの名無しさん
07/07/01 14:33:54
delete bで開放するのいいけど
その後メモリ取ろうdeleteした近辺にnewなんかされると
悲惨なことになるぞw
298:デフォルトの名無しさん
07/07/01 14:35:24
>delete bで開放するのいいけど
良くない
299:デフォルトの名無しさん
07/07/01 14:39:20
言語的にだめなのは分かるんだけど
PODの場合で
new[]で確保したのをdeleteでシメた場合に
実際に不具合があるような実装って
おおいの?
300:デフォルトの名無しさん
07/07/01 14:39:43
結論としては色々とややこしいから最初は配列なんか使わずにコンテナつかっとけってこと?
301:デフォルトの名無しさん
07/07/01 14:41:50
>>300
でも
const char *bad_words[] = { "fxxk", "pxxsy", "axxl", "cxxt", ... };
みたいなのは配列が便利じゃね?
302:デフォルトの名無しさん
07/07/01 14:42:36
>>299
すくないとか言ったら使いそうだから言わない。
303:デフォルトの名無しさん
07/07/01 14:43:38
>>302
いや、実は見たこと無いから聞いてみたんだけど(ボソッ)
304:デフォルトの名無しさん
07/07/01 14:45:28
見たことないけど、
将来デバッグモードで変なことするコンパイラが
出てくる可能性もなくはないと思う。
305:デフォルトの名無しさん
07/07/01 14:46:14
>>299 それは実装に不具合があるわけじゃねーぞ。
306:デフォルトの名無しさん
07/07/01 14:47:44
>>305
落ちるとかバグるとかそういう環境は多かったりするのか?
という話なわけで。
307:デフォルトの名無しさん
07/07/01 14:48:13
>>305
いや勿論そういう意味じゃなくて、
メモリが解放されなかったり
ヒープが壊れたり
無限ループに陥ったり
ハードディスクが初期化されたり
といった問題が生じるかどうか、という意味
308:デフォルトの名無しさん
07/07/01 14:51:56
>>301
new[]で確保するのでなければ別に構わないと思う。
309:デフォルトの名無しさん
07/07/01 14:56:57
>>307
そんな問題が生じたこともないし生じるようにも思わないが生じる可能性はある。
310:デフォルトの名無しさん
07/07/01 15:10:03
int a[] = new int[10];
何が問題なの?
311:デフォルトの名無しさん
07/07/01 15:12:32
そもそもコンパイラ通らないだろ
312:デフォルトの名無しさん
07/07/01 15:12:34
>>310
コンパイルエラー
313:デフォルトの名無しさん
07/07/01 15:13:58
まずコンパイルしてからなんか家w
314:デフォルトの名無しさん
07/07/01 15:15:37
int a[] =(int[]) new int[10];
315:デフォルトの名無しさん
07/07/01 15:21:46
C、C++の基本的なことは勉強してきました。
それで簡単なGUIアプリから作ってみたいのですがVisual C++とDelphiで迷っています。
DelphiだとPascalを勉強しなければいけないそうですが大変でしょうか?
C、C++が無駄になりそうで怖いですが。
C++を勉強してきた場合、Visual C++のほうがいいでしょうか?
316:デフォルトの名無しさん
07/07/01 15:21:52
コンパイルエラー
317:デフォルトの名無しさん
07/07/01 15:23:32
>>315
C/C++ 勉強したなら VC++ 使えば?
318:デフォルトの名無しさん
07/07/01 15:26:37
そしてうっかりCLRアプリケーションのプロジェクトを選択して
C++/CLIを勉強する羽目に。
319:デフォルトの名無しさん
07/07/01 15:27:10
>>315
どれくらいのレベルか知らないが、勉強のためVC++をススメておく
DelphiでもCやC++で勉強してきた基礎は無駄にならないと思うけどね
320:デフォルトの名無しさん
07/07/01 15:27:41
Delphi には将来性が・・・
321:デフォルトの名無しさん
07/07/01 15:29:13
int *a[] = new int[10];
322:デフォルトの名無しさん
07/07/01 15:29:48
int *a[|] = new int[00];
323:デフォルトの名無しさん
07/07/01 15:32:27
int **a = new int*[10]
for( int i = 0; i < 10; ++i )
a[i] = new int;
for( int i = 0; i < 10; ++i )
delete a[i];
delete [] a;
324:デフォルトの名無しさん
07/07/01 15:33:57
int (*a)[10] = new int[10][10];
delete[] a;
325:デフォルトの名無しさん
07/07/01 15:35:19
delete[] you;
326:デフォルトの名無しさん
07/07/01 15:40:56
Segmentation fault (core dumped)
327:デフォルトの名無しさん
07/07/01 15:52:25
std::vector<int> a(10);
328:デフォルトの名無しさん
07/07/01 15:53:19
std::vector<inpo> you(10);
329:デフォルトの名無しさん
07/07/01 17:10:26
struct A { int x; };みたいなのをA a;と宣言してこれを
std::cout << a;のようにした時にメンバであるxの値を出力するように変換関数を定義したいんですが
どうすれば良いんでしょう?
operator std::string();とやってみましたが変換できないようです
330:デフォルトの名無しさん
07/07/01 17:16:12
>>329 operator << (std::ostream&, A const&)
331:デフォルトの名無しさん
07/07/01 17:16:22
std::ostream& operator<<(std::ostream& os, A& a) {
os << a.x;
return a;
}
A内で上の関数をfriend宣言しておく
332:デフォルトの名無しさん
07/07/01 17:17:31
>>331 friend は要らんだろ
333:デフォルトの名無しさん
07/07/01 17:20:35
>>329
cout << static_cast<std::string>(a);
とやるか、
std::ostream& operator<<(std::ostream& os, const A& a) { return os << a.x; }
でも定義汁
334:デフォルトの名無しさん
07/07/01 17:28:57
皆様の回答を参考にぐぐったら出てきました
URLリンク(www.higlab.k.dendai.ac.jp)
なるほどオーバーロードとfriendの複合技ですか、さらにostreamを戻す事で連結も可能と…
かなり使えそうな方法ですね、助言ありがとうございました!
335:デフォルトの名無しさん
07/07/01 17:40:54
>>334
ここまで必要になるか分からないけど、
class A {
public:
virtual void print(std::ostream &os);
};
std::ostream& operator<<(std::ostream& os, const A& a) { a.print(os); return os; }
とやった方が、もしかしたらいいかもしれない。
こうすると継承クラスでprintを再定義できる。
336:334
07/07/01 18:02:45
>>335
なるほど継承ですか、実行時の多態性については意識し取りませんでした
確かにこの振る舞いをもたせたいのがAだけに限るわけではないですしね
とりあえず参考にしてNVI使ってこうやってみました
// 構造体A周辺の定義
struct Base {
public: void print(std::ostream& os) const { _print(os); }
private: virtual void _print(std::ostream& os) const =0;
};
struct A : public Base {
private: void _print (std::ostream& os) const { os << x; }
public: int x;
};
std::ostream& operator<<(std::ostream& os, const Base & base)
{ base.print(os); return os; }
// 使用例
#include <iostream>
int main() {
A a;
a.x = 1;
std::cout << a;
}
…しかし鶏を捌くのに牛刀をなんとやらですね
実際に使うとなればここまでする必要も出てきそうな気もせんでも無いですが
337:デフォルトの名無しさん
07/07/01 18:27:37
この場合のNVIって何の意味があるの・・・?
338:デフォルトの名無しさん
07/07/01 18:29:47
最近おぼえて使いたくなったんだろ。気にするな。
339:デフォルトの名無しさん
07/07/01 18:35:35
NVI
ってなんですか?
340:デフォルトの名無しさん
07/07/01 18:40:11
>>339 ググレカス
341:デフォルトの名無しさん
07/07/01 18:49:35
NVI=non virtual interface のこと。つまり↓
struct Hoge {
void hage(T1 arg1, T2 arg2) {_hage(arg1, arg2); }
protected:
virtual void _hage(T1 arg1, T2 arg2) = 0;
};
下位クラスには_hageを継承してもらう。
なぜこんなことをするのか)
公開仮想インターインターフェイスが果たす目的は以下の二つ(と言われてる^^)
1. 使う人に使い方(インターフェイス)を提供する
2. 派生クラスに「こういうふうにメソッドを継承して下さい」とカスタマイズの規約を提供している
たとえば、NVIを使わず下位クラスがhageをそのまま継承してしまうと
Hoge#_hageのインターフェイスを変更したときに下位クラスすべてのメソッドを書き直す必要があるんだけど、
もしNVIを採用していればそういうことにはならない。
逆にインターフェイスを変更せず、実装メソッドの方だけを変更することもできる。
>>336の場合、インターフェイスが変更される可能性は全く無くて、無駄に複雑にしてるだけだと思う。
342:デフォルトの名無しさん
07/07/01 18:52:31
そもそも値型のクラスの継承はあまり宜しくない
343:デフォルトの名無しさん
07/07/01 18:54:58
値型のクラス???
344:デフォルトの名無しさん
07/07/01 19:11:16
Value classの事
・publicなデストラクタとコピーコンストラクタと代入演算子を持ち
・デストラクタを含め仮想関数を持たなくて
・具象クラスであり抽象クラスでない
・スタック上や他のクラスのメンバとしてインスタンス化される
とまぁおおよそ組み込み型のように振舞えるものでこういうのは継承じゃなくて委譲を使うべきらしいけど、
実際のところはそれが妥当なのか場合によるからよくわかんねけど
俺は複雑な構造体を継承してえらい目にあったので「あまり宜しくない」と思うようになった
ちなみに出展はmore effective C++あたりだったと思う
345:341
07/07/01 19:23:42
>>344
Value classなんて初めて知った。
全部が全部ってわけじゃないけど、ほとんどは>>344のいうとおりだろうね。
ただ、サンプルプログラムでそういうことを考えちゃうと
バーチャルなデストラクタや、privateなoperator =を書く必要が出てきて
全体的に焦点がぼやけてしまいまふ。
>>341ではとりあえずそういうことは無視させてもらいますた^^
346:デフォルトの名無しさん
07/07/01 19:29:32
>>344
そんな区別意味無いだろ。
public なデストラクタが virtual じゃないクラスを継承したのが間違いだったんじゃないの?
value class って用語も検索結果が日本語ページ多すぎで胡散臭いし。
347:デフォルトの名無しさん
07/07/01 21:00:20
値のセマンティクスを持つクラスと言いたいのでは?
ググったらこんなページを見付けたが、こういう話だろう。
URLリンク(www.ogis-ri.co.jp)
348:デフォルトの名無しさん
07/07/01 21:09:43
つうかそういうクラスはそもそも継承を前提に作ってないだろ
他言語ならsealedクラスになってるタイプのクラス
349:デフォルトの名無しさん
07/07/01 21:29:11
で>>342に戻ると
良いサンプルってやっぱ難しいんだね
350:デフォルトの名無しさん
07/07/01 21:33:35
複雑なものを扱うためのテクニックを簡単なサンプルで見せても
無意味にしか見えんからのう
351:デフォルトの名無しさん
07/07/01 22:17:49
とりあえず、NVIならこの程度のサンプルでも十分通用するね
352:デフォルトの名無しさん
07/07/01 22:18:38
NVIってExceptional C++で勉強しましたか?
353:デフォルトの名無しさん
07/07/01 22:22:03
Exceptional C++―47のクイズ形式によるプログラム問題と解法
Exceptional C++ Style―40のクイズ形式によるプログラム問題と解法=スタイル編 Exceptional C++ Style―40のクイズ形式によるプログラム問題と解法=スタイル編
これって何が違うんでしたっけ?
354:デフォルトの名無しさん
07/07/02 00:12:21
4バイトint型 num = 10,000,000の16バイト表現を、
ビッグエンディアンで
char型 d[10]のd[5]~d[8]の各要素に格納したいと思っております。
numを表現する4バイトそれぞれの値を取得するためには
どうすればいいのでしょうか?
char *p = (char *)num; // numのポインタを取得
d[5] = p; // 1Byte分の値を取得
p++; // charのポインタなので1Byte分ポインタを変更
とやることを考えたのですが、pの値がおかしな値になります。
どのようにコーディングするとよいでしょうか?
355:デフォルトの名無しさん
07/07/02 00:14:59
char *p = (char*)#
の間違いだと思うのだがどうよ
356:デフォルトの名無しさん
07/07/02 00:17:24
たびたび、すみません。
スレッドに複数の引数を渡したい者です。
//スレッド関数
void Thread_f(void* StructData){
//何にもしないスレッド StructDataは、下で出てくるData構造体
}
メインのほうで、スレッド作成
Data data; //Dataっていう複数の引数を渡すための構造体
for(int i=0;i<n;i++){
data=datalist[i];//datalistは、Data構造体のポインタ配列 代入してから渡してます
handle[i] =(HANDLE) _beginthread(CameraThread,0, (void *)&data);
Sleep(3000); i++;
//スレッド立ち上げてる間に、全部スレッド側で全部datalist[n]になってしまうので。
//ちょっとSleepしました。すごいダメな処理です。すみません。
}
n=1のときは、エラーでないです。
nが2より大きいと、動くことは動きますが、×(ウィンドウの閉じるボタン)
で閉じると、
-ElnvalidPointerクラスの例外を生成しました。
-'無効なポインタ操作'
-プロセスは停止しています。・・・・
というエラーがでます。
”同じポインタを 2 回破棄したり,すでに破棄したポインタを参照したりすると出る”
とネットの掲示板でありました。
同じ関数のスレッドに、それぞれ違うdataを渡したいときは、スレッド関数に引数渡さないほうがいいですか?
248さんが言ってたのは、このことかなぁと思って、今は、引数渡さない方法でやってますが。
上記のプログラムに、手を加えてエラーで無い方法ないでしょうか。
357:デフォルトの名無しさん
07/07/02 00:21:55
あっ、CameraThreadは、ほんとの関数名でした。
Thread_fに、訂正お願いします。
358:デフォルトの名無しさん
07/07/02 00:23:23
>>356
だから、スタック上のオブジェクトのポインタをスレッド関数に渡すなと。
呼び出し側のコンテキストが平然と進行しつづけてスコープ抜けた瞬間に
無効になっちゃうだろが。
malloc()やnewでフリーストア上にオブジェクトを確保して、その
ポインタを渡すんだな。無論渡されたスレッド側で不要になったら
破棄すること。
本当はC++使ってるんなら、スレッドをラップするクラスを作るのが良いが
それはまあいい。
359:354
07/07/02 00:23:58
>355
ご指摘どおりです。
char *p = (char *)# // numのポインタを取得
d[5] = *p; // 1Byte分の値を取得
p++; // charのポインタなので1Byte分ポインタを変更
d[6] = *p;
p++;
・・・
としているのですが、値が正常にとれません・・・
360:デフォルトの名無しさん
07/07/02 00:32:53
>>358
レスありがとうございます。
new演算子は、Dataをでしょうか?
Data *datalist = new Data[N];
これで処理してます。
361:デフォルトの名無しさん
07/07/02 00:34:23
>>360
それなら、そのdetalistをそのまんま(void*にキャストして)渡せばいい
362:デフォルトの名無しさん
07/07/02 00:42:56
>>361
data=datalist[i];
これを、なくして
handle[i] =(HANDLE) _beginthread(CameraThread,0, (void *)&datalist[i]);
ということですよね。
これでも、同じ症状です。
dataにコピーしてから、渡すとエラーが消えるかも、
と思って入れたおまじないの処理なんです。
363:デフォルトの名無しさん
07/07/02 00:46:27
>>362
ちょっとまて
意味わかんなくなってきた
スレッドをN個起動してて、i番目のスレッドにdatalist[i]を渡したいのか
だがそれだと、datalist[]の破棄はどうする?
いつどこで誰がやってるんだ?
364:デフォルトの名無しさん
07/07/02 00:48:21
今日ここで俺がやる
365:デフォルトの名無しさん
07/07/02 00:55:11
メインの方で、スレッドの処理が終わるのを、待ってからです。
スレッドが終わるまで待ちます。
for (int i=n; i>0; i--){
while(WaitForMultipleObjects(n, (CONST HANDLE *)handle,TRUE, 500) == WAIT_TIMEOUT){//タイムアウトなのでループ}
}
delete data;
366:デフォルトの名無しさん
07/07/02 00:57:35
>>365
datalist じゃないのか? delete [] じゃないのか?
367:デフォルトの名無しさん
07/07/02 01:03:11
>>365
その i でまわしてる for ループは何のつもり?
WaitForMultipleObjects() で全部待つんだろ?
あと、戻り値はちゃんとチェックしろよ。
(CONST HANDLE *) とかいうキャストも要らんだろ?
っていうか前のコードから要らないキャスト多すぎだ。
368:デフォルトの名無しさん
07/07/02 01:04:02
お手数かけてすみません。
delete datalist;
です。
369:デフォルトの名無しさん
07/07/02 01:04:48
>>365
よくわからんが、メモリバリアを_beginthreadex()の前後あたりに
挿入すると状況が改善されるかも
370:デフォルトの名無しさん
07/07/02 01:05:24
>>368
それじゃダメだ。 delete [] 使え。理由は聞かずにちょっと前のログを見ろ。
371:デフォルトの名無しさん
07/07/02 01:27:44
while(WaitForMultipleObjects(n, (CONST HANDLE *)handle,TRUE, 500) == WAIT_TIMEOUT){}
スレッドが終わったっていう合図以外は、ここでループしてます。
タイムアウト以外というコメント不正確でした。
forで、n回繰り返すと、n個のスレッドが終了するのを待ったことになります。
delete datalist [];
deleteの使い方理解していないので、
ちょっと時間掛かるかもです。構文エラーとか出てきます。
372:デフォルトの名無しさん
07/07/02 01:29:11
構わんよ、おつまみみたいでみんな喜んでるみたいだし
373:デフォルトの名無しさん
07/07/02 01:29:40
delete [] datalist;
ああ、反対でした。
同じエラー出てきました。
374:デフォルトの名無しさん
07/07/02 01:36:17
>>371
> forで、n回繰り返すと、n個のスレッドが終了するのを待ったことになります。
WaitForMultipleObjects() の第3引数は BOOL fWaitAll で TRUE の時は
その呼び出しで全部待つ。戻り値にはエラーもある。仕様をちゃんと見て使え。
375:デフォルトの名無しさん
07/07/02 01:43:53
delete [] datalist;
コンパイル通りました。
-ElnvalidPointerクラスの例外を生成しました。
-'無効なポインタ操作'
-プロセスは停止しています。・・・・
やっぱり、これが出てきてしまいます。。。
スレッド1個(n=1,N=1)にすると、大丈夫なんですよね。
あと、>>356で、Sleepの次i++が入ってまずが
頭がおかしくなって、入力してしまったのかもしれません。
すみません。
376:デフォルトの名無しさん
07/07/02 01:47:27
疲れてるなら休めば?スッキリしてないと頭の回転悪いよ
377:デフォルトの名無しさん
07/07/02 01:51:18
ぶっちゃけそのレベルで
メダパニとラリホーかけられてちゃ
どんな間違いやってても不思議じゃないな
378:デフォルトの名無しさん
07/07/02 02:02:34
>>374
ありがとうございます。
WaitForMultipleObjectsで、苦労したんですが
なんか思い出だしてきました。
結局、スレッドの方では、なんにもしてないので、
newで渡すのがだめな気がしてきました。
379:378
07/07/02 02:14:02
今日は、ちょっとギブアップします。
ありがとうございました。
380:デフォルトの名無しさん
07/07/02 09:25:30
>>315
間取ってC++Builder使えばいいんじゃね?
381:デフォルトの名無しさん
07/07/02 09:42:53
>>332
A内でfriend宣言しておかないとA.aのように参照した場合
もしaがprivateやprotectedだった場合エラーになる。
382:デフォルトの名無しさん
07/07/02 09:55:23
>>381
この場合はstructで全部publicだから要らんと言われてただけでしょ
383:378
07/07/02 10:18:40
378です。
シンプルなプログラムを別に作って、
new演算子でも大丈夫なこと確認しました。
それで、本物の方のプログラムの方をGUIの部品とか
1個ずつはずしていって、シンプルなプログラムに近づけていったところ。。。
(6時間後・・・)
void __fastcall TForm1::Button17Click(TObject *Sender)
{
//なにもしないボタンです。これから実装します。
}
ボタン17を削除して、またボタン作ったら
なぜか閉じるボタンで、ポインタエラーがでなくなりました。
ということで、new演算子で渡しても大丈夫みたいです。
ありがとうございました。
384:デフォルトの名無しさん
07/07/02 13:07:16
VC7でswitch内で
switch (val)
{
//コメント
//コメント
case 1:
~~
break;
}
こんな感じでcaseの上に複数コメントがあるブロックが多いと、
デバッグの時のブレークポイントや、実行時の位置が
おかしくなることがあるみたいなんですが、どこかに詳細な
報告はありませんか?
検証が甘いですが、VC2005でも同じ現象が起こるみたいです。
385:デフォルトの名無しさん
07/07/02 14:12:08
int (*a)[] = new int[10];
386:デフォルトの名無しさん
07/07/03 17:39:39
質問です。
Foo::Foo() : m1(), m2(), m3() {}
このようなFooクラスのコンストラクタにおいてm2のコンストラクタが例外を投げたとき、
既に初期化が完了していたm1のデストラクタが呼ばれることは「C++の規格で保障」されているのでしょうか?
VC++2005で確認した限りではその通りの動作をするようですが…
387:デフォルトの名無しさん
07/07/03 17:44:42
保証されてる。
Foo::Foo() try : m1(), m2(), m3() { } catch(...) { }
みたいにしてキャッチすることもできるけど、
例外は必ず再送出される。
388:386
07/07/03 17:51:16
>>387
ありがとうございます。
> Foo::Foo() try : m1(), m2(), m3() { } catch(...) { }
そういえば function-try block なんて見たのは久々^^;
389:デフォルトの名無しさん
07/07/03 18:04:46
コンストラクタが失敗して例外を投げたときって、
中途半端にコンストラクトされた状態だと思うんだけど、
デストラクタは呼ばれないわけだよね?
メモリリークの原因にならないのかな?
390:デフォルトの名無しさん
07/07/03 18:07:50
if(pMem){ delete pMem; }
でおk
391:デフォルトの名無しさん
07/07/03 18:09:32
>>389
ちゃんと自分で例外をキャッチして開放してくだちぃ。
それが嫌なら vector とかスマートポインタとか使ってデストラクタに任せてくだちぃ。
392:デフォルトの名無しさん
07/07/03 18:12:42
>デストラクタは呼ばれないわけだよね?
catchしたら呼べばいいじゃん。
393:デフォルトの名無しさん
07/07/03 18:12:52
>>390
deleteはNULL渡したら勝手に無視してくれなかったっけ?
394:デフォルトの名無しさん
07/07/03 18:13:12
してくれる。
395:デフォルトの名無しさん
07/07/03 18:13:59
仕様上は無視することになってるが、
昔の VC++ あたりはしてくれなかった記憶がある。
396:デフォルトの名無しさん
07/07/03 18:20:11
そうだっけ?
もしそうなら、そのときはその仕様がまだなかったんじゃないか
397:デフォルトの名無しさん
07/07/03 18:21:03
URLリンク(www.google.com)
なんてググると、DirectXあたりで
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
こんなマクロが出てきたりするからてっきり勘違いしていた。
398:デフォルトの名無しさん
07/07/03 18:24:56
>>396
VC6 あたりまでそうだったと思う。
この仕様があるかどうか微妙な時代かもしれん。
399:デフォルトの名無しさん
07/07/03 21:20:22
SAFE_DELETEの利点は変数にぬるぽを代入してくれる点
解放後にアクセスしようとすると素直に落ちてくれる
400:デフォルトの名無しさん
07/07/03 21:28:18
ニートで暇だからプログラミングの練習でもするかとゲームを作り始めたのですが
いきなり挫折しました。かれこれ4時間ほど睨めっこしてるのですが
どこに間違いがあるのか検討つきません。ご教示お願いします。
環境はコンパイラはBoland C++ 5.5 + BolandDeveloper 1.221
WinアプリケーションでDXライブラリです。(多分環境は関係無いんでしょうが)
メッセージはint型はchar *型に変換出来ないと出ます。
一部抜粋
FILE *fp;
char *file_name="map1.txt",buf[99];
char* p;
char* q;
if((fp=fopen(file_name,"r"))==NULL)return-1;
このぎょうです。→ while((fgets(buf,sizeof(buf),fp))!=EOF){
j=0;
p=strtok(buf,",");
map_data[i][j]=atoi(p);
j++;
while(p!=NULL){
p=strtok(NULL,",");
if(p!=NULL){
map_data[i][j]=atoi(p);
j++;
}
}
i++;
}
fclose(fp);