【初心者歓迎】C/C++室 Ver.39【環境依存OK】
at TECH
1:デフォルトの名無しさん
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)
A k+20.0
B (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内部で排他制御しても何の意味も無いぞ。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4816日前に更新/194 KB
担当:undef