typedef struct { unsigned short HOGE_COUNT; char Reserve[14]; char data[2]; } HOGE_HED; HOGE_HED* fpHOGE; HOGEHOGE* fpHOGEDATA; fpHOGEDATA = (HOGEHOGE *)fpHOGE->data; ざけんな
ワロタ
アハハハハハ …ハァ
長さが決まってない構造体を扱う場合はこうするとネットで見たのでそれをまねしたんですけど・・・
>9 たぶん、それは可変長の文字列を扱うための、 あまり行儀がよくないがよく使われている方法だろう まあここだけじゃなさそうだから少し待て
void HogeFree(HOGEHOGE* wfp) { free(wfp); return; } これはねーよ・・・
12 :
924 :2008/07/09(水) 13:47:13
>>11 機能を分割してて、他から呼ばれる予定で作ったのでまだ未使用
ですしフェールセーフもいれてません。
流し読みした感じ 一応手前の確保は sizeof(HOGEHOGE) * ret 増加分は見込んでるのか しかし -2 ってマジックワードは何よ? あと malloc() の戻りでないアドレスに対する free() は保証外じゃなかったっけ? そこらへんの落とし穴は大丈夫なのか?
>>4 wfp = fpEntTy[i];
case -2 :
if (wfp->prevdata == NULL) {
wfp2 = fpEntTy[i];
}
free(wfp);
wfp = wfp2;
if ( wfp != NULL ) wfp = (HOGEHOGE *)wfp->nextdata;
この流れがあやしい
wfpとwfp2は同じもの(fpEntTy[i])を指してるよな?
wfpはfreeしてしまったんだから、同じ場所を指してるwfp2も触ってはだめなんじゃないか?
>あと malloc() の戻りでないアドレスに対する free() は保証外じゃなかったっけ? >そこらへんの落とし穴は大丈夫なのか? 今それが一番くさいです。 なのでリストから切り離したあとfreeする部分をコメントにしたらフリーズしませんので
-2はヘッダのchar[2] 分でしょ。
LineCount()とChkIndexの仕様は
18 :
デフォルトの名無しさん :2008/07/09(水) 13:59:14
if ((fp = fopen(fname, "r")) == NULL) { printf("%s が見つかりません\n",fname); } 読み込むファイル名の入力処理なんですが、VSだと古い形式と警告されます。 より安全にするにはどう書いたらいいんですか?
LineCount() は リストに登録する対象となるデータの数字を返すだけです。 ChkIndex() はリストの元となるデータnコのうち現在どこまで処理したかを返すだけです。 呼ばれると数字を返したあと内部で持ってるカウンターをインクリメントします。
あっちこっちに不要なキャストがあるな んでとりあえず if (wfp->prevdata == NULL) { wfp2 = fpEntTy[i]; } else { wfp2 = wfp->prevdata; } HogeDel(i,wfp); wfp = wfp2; break; これは HogeDel(i,wfp); wfp = fpEntTy[i]; break; の間違いじゃないのか? その下も同様に HogeDel(i,wfp); //free(wfp); wfp = fpEntTy[i]; break;
実は、を連発するあたりでだいぶなえてしもうた 有志ガンガレ
22 :
924 :2008/07/09(水) 14:05:09
>>20 やってることはリストをたどりながら処理をし(ChkSwitch)不要になった
ら戻り値によって途中で削除ということなので
wfpがリストの中ほどなのかリストの一番先頭なのか
を判断してます。
>>19 int index = ChkIndex(); -(1)
if (index < fpHOGE->HOGE_COUNT) {
...
wfp = (HOGEHOGE *)(fpHOGEDATA + ChkIndex()); -(2)
(1) の戻りが HOGE_COUNT-1 の場合
fpHOGEDATA は 0〜HOGE_COUNT-1 の HOGE_COUNT個確保しているにもかかわらず
(2) で HOGE_COUNT を返すことになり 確保外のアドレスを指示することになっている
>>18 if(fopen_s(&fp, fname, "r")){
printf("%s が見つかりません\n",fname);
}
25 :
デフォルトの名無しさん :2008/07/09(水) 14:09:52
>>24 どうも!
この辺の解説サイトありますか?
>>22 じゃあこうだろう
wfp2 = wfp->nextdata;
HogeDel(i,wfp);
if(ChkSwitch[wfp->Hoge06](i,wfp) == -2) {
free(wfp);
break;
}
wfp = wfp2;
28 :
27 :2008/07/09(水) 14:15:38
あ、break消し忘れた まあとにかく、元のソースだとwfp2に入れてる値がおかしい wfp2 = fpEntTy[i]; としても、その後HogeDel()で fpEntTy[i] が変化してもwfp2は変わんないだろ
>>27 それだと常に削除の対象です・・・
ChkSwitchの戻り値が-1と-2は削除それ以外の場合、リストはそのままなんです。
つーか、下手に技巧かまして初期に配列確保して動かないコード書くぐらいなら 単品 malloc() を n回呼び出し+途中の追加も単品 malloc() のほうがマシじゃね?
>>29 switch(ChkSwitch[wfp->Hoge06](i,wfp)) {
case -1:
wfp2 = wfp->nextdata;
HogeDel(i,wfp);
wfp = wfp2;
break;
case -2:
wfp2 = wfp->nextdata;
HogeDel(i,wfp);
free(wfp);
wfp = wfp2;
break;
default:
break;
}
宿題スレだな
ついでにこっちも直しとく // // 領域確保部分抜粋 // int size = sizeof(HOGE_HED) + sizeof(HOGEHOGE) * ret; fpHOGE = malloc(size); if (fpHOGE == NULL ) return -18; memset(fpHOGE,0x00,size); fpHOGE->HOGE_COUNT = ret; fpHOGEDATA = (HOGEHOGE *)(fpHOGE+1);
>>33 >fpHOGEDATA = (HOGEHOGE *)(fpHOGE+1);
あーなるほど。こうすればいいんですね。
これでchar data[2];が不要になりますね。
35 :
924 :2008/07/09(水) 14:35:13
>>30 まー近い挙動のものにシューティングゲームなんかがありますけど
ゲームを構成する素材(背景や敵本体)は固定になりますが、自機や敵が吐き出す弾
は事前に・・というわけにはいきませんよね?
それでこういった2種類の領域の確保の仕方になってます。
>>31 ありがとうございます。
これでうまくいきました。
最近大改造してようやく今のスタイルにこぎつけたので混乱してました。
>>35 は? 全て固定にしろと言っているのではなく、
全て動的にしといて たまたま固定分は先にやっちゃったね って構造のことを指しているのだが?
全て敵が吐き出す弾扱い。 背景や敵本体は初期化の時に1個1個追加してくだけじゃん
まーいいじゃないですか
あの変なポインタ操作みてるとヘッダ+データになったバイナリファイルをまとめて
読み込んだりしてるんでしょ?
>>31 で動いたってことは領域の確保の問題じゃなく単にリスト操作の間違いだったんだし。
>>37 リストをバイナリファイル保存するのは… テラオソロシス
ちゃんと繋ぎ替え作業しないといけないしね。
そこだけ違うコード書くってことは、そこで間違う可能性もあるわけだし…
>>31 の修正で動く
>>31 のせずに、構造体のメンバ入れ替えで挙動変化する
のは、どういう副作用かなぁ free後次の alloc する何か次第なんだろうけど…
39 :
デフォルトの名無しさん :2008/07/09(水) 15:21:54
学校の課題なんですが、どうやればいいかいまいちわかりません。 なので、全体の流れだけでもいいので教えてくれませんか? 以下、課題の内容です。 200x200ピクセルの画像の中に三角形、四角形、円、楕 円を用いて絵を作成しよう。その際、関数を用いて作成し ましょう。 図形の作成、移動、回転などには関数を用いること。 効率よく関数を使って、絵を作成しましょう。 main関数は画像配列の確保と関数の呼び出しで作成する。 出力ファイル名(art.bmp)
要するにfreeした後の領域を使おうとしてたわけで、 おそらくアロケート情報が入っていた領域先頭付近のメモリの書き換えが発生したんだろう だからポインタを先頭に置いてたらおかしくなった 後ろに配置してたときはたまたま情報が壊れずに残ってたと
>>38 別人28号、余談だが俺いま、双方向ツリーデータのべた書き保存してるよ。
元々はテキストで保存読込みしていたが、あまりにも遅いので、いろいろ考えた据え
メモリーイメージべた書きにした。もちろんアドレス変換つきで。
数十Mぐらいのデータ読込みに分かかってたのが一瞬で読み込めるようになった。
いや〜あまりの速さに、TPOを考慮しないプログラムもいいなと思った。(チラシの裏
そういうことやね
>39 1)各画像をビットマップ描画する関数を作る。 このとき、関数の引数で図形の基準座標や大きさ、角度などを指定できるようにする。 指定の方法はいろいろあるが、かなり引数が多くなることもある。 その場合には必要な変数を構造体に詰めこんでそのポインタを渡すと楽。 対象のビットマップは、引数で渡してもいいし、どうせ1個しか書かないなら、 グローバル変数で確保してもいいだろう。 2)mainで、1)で作った関数に適当に数値を与えて呼び出し、ビットマップに描画する。 3)作ったビットマップをファイルに書き出す(何かメソッドがあるはず)。
>>40 なるほど。
ある意味先頭に持ってきたためにバグが発覚してよかったのかもなw
>>41 まあリストを保存するっていったって、保存ルールさえ決めちゃえば
問題ないしな。
46 :
デフォルトの名無しさん :2008/07/09(水) 15:32:28
char func(char *hoge){ char hoge2[256]; 処理 return *hoge2; } とする関数を定義しました。 main関数で char test[256]; *test= func("文字列"); って書いたんですが、testにゴミしか入りません・・・ 正しいやり方を教えてください
char *func(char *test, char *hoge){ char hoge2[256]; 処理 return strcpy(test, hoge2); } main() { char test[256]; func(test, "文字列");
int func(const char *hoge1,char *hoge2){ } char test[256]; func("文字列",test); でfuncの中でtestに書き込みできるよ
49 :
39 :2008/07/09(水) 15:37:49
>>43 ありがとうございます!
関数を作るってところが授業でもよくわかっていないのですが、どんな感じかソースを少し書いてみてくれませんか?
質問ばかりですいません。
宿題スレに行けよ
>>49 細かい部分は処理系の用意しているグラフィック機能の詳細による
たぶん実際にはC++なんだろうから、ビットマップオブジェクトクラスのメソッドを調べて使うこと
void square(BITMAP bitmap, POINT *points)
{
bitmap->pen->color=BLACK;
bitmap->pen->move(points[0].x, points[0].y);
bitmap->pen->line(points[1].x, points[1].y);
bitmap->pen->line(points[2].x, points[2].y);
bitmap->pen->line(points[3].x, points[3].y);
bitmap->pen->line(points[0].x, points[0].y);
}
あくまで感じ
引っ越したときは引越し通知くらいほしいよね
マルチかと思ったら別人だったようだ
本とかによく出てるプログラムをそのまま打ち込んでうまくコンパイルしてくれるコンパイラって無いの?
それができりゃあプログラマの仕事がなくなるな
換字式暗号について聞きたいんですが、c言語で[a,b,c]を[g,C,f]に変換するようなプログラムってどう作ればいいですか? ちなみに文字列に規則性はないです。
それはタイパーの仕事じゃ? コンパイルできないといっているコードはコード片だったりしないのかな
微妙に違う内容でマルチすんなw
>>57 rand関数で適当にASCIIコードを進める
>>55 本と同じ環境、同じコンパイラーならそのまま動く。
しかし、半年や1年で、OSもコンパイラーも仕様さえも変わってしまう時が有る。
一つの変化は数年だが、環境は多くのソフトで成り立つので。どれかがすぐに変わるのはザラ。
qあwせdrftgyふじこ
標準関数かAPIに文字列の置き換え関数ってないの? 自分で作ったけどいまいち信用できない(速度的に)
>>63 cならそれこそマクロで皮だけ作ったら?
#define hogehoge(A,B,C,D) { API_hoge(A,B,C,D) };
あーーーーーーすまんぼけてましたorz 文字列置き換えって言われてもどう置き換えるの?
文字列の配列データーを作って、適当に文字列入れて、 文字のコードで配列を引く、これが単純。
>>57 char *stra = "abcdefghijklmeo.....";
char *strb = "gCfEjBm.....";
で文字が一致したところで置き換える
>>67 strb[data - 'a']
の何が不満なの?
>>65 こんな感じなんだけど非効率かどうか自分にはわからない
//szSrcの中からszKeyを探してszRepで置き換える
//置き換えた数を返す
int strrpl(char *szSrc, char *szKey, char *szRep) {
int nRepTime = 0;
size_t nSrcSize = strlen(szSrc);
size_t nKeySize = strlen(szKey);
size_t nRepSize = strlen(szRep);
char *szCpySrc = new char[nSrcSize + 1];
strcpy(szCpySrc, szSrc);
*szSrc = 0;
char *cp = szCpySrc;
char *_cp = szCpySrc;
while (cp = strstr(cp, szKey)) {
*cp = 0;
strcat(szSrc, _cp);
strcat(szSrc, szRep);
cp += nKeySize;
_cp = cp;
nRepTime++;
}
strcat(szSrc, _cp);
delete [] szCpySrc;
return nRepTime;
}
>>68 文字コードが順番じゃなくても使える
ASCII限定でも問題ないんだろうけど
EBCDIC でやったときは"ABCDE・・・だったなー
72 :
sage :2008/07/09(水) 21:06:35
学校の課題でC言語が出てしまったのですが、さっぱり分かりません… あつかましいかもしれないですが、どなたか教えてください… @「キーボードから10個の数値を入力して、10個の数値の最大値と最小値を表示するコードを 記述せよ」 A「キーボードから数値を入力し、その数が素数か否かを判断するコードを記述せよ」 よろしくお願いします。
ごめんなさい、1を見てませんでした。宿題スレに行ってきます。
74 :
デフォルトの名無しさん :2008/07/09(水) 22:15:00
リスト構造がよく分かりません。 構造体は理解できるのですが、なぜそれが繋がっていくのか(繋げれるのか)がどうにも・・・。 抽象的な質問ですみませんが、どなたかお願いします。 例となるようなソースなどもあると助かります。
76 :
74 :2008/07/09(水) 22:21:33
>>75 大まかには理解している、と思うんですが・・・。
intやcharなどの関数のメモリの先頭の場所で、
その関数を指すのと、その関数の場所を指すのは同じこと。
というくらいの理解なんですが・・・。
>>76 構造体の中に自分自身と同じ構造体をさせるポインターを持たせてあって
それでつないでるのがリストです。
宝箱の中に 「宝」と「次の宝箱の場所」が入ってるようなもんだ
>>77 どう繋ぐかが分からず・・・。
>>78 その「次の宝の場所」は、どういう処理になっているのでしょうか?
その「次」が無数に増える場合、最初から指定しておくのは不可能だと思うんですが、
どうやってその「次の場所」を指定すれば良いのか分からないのです。
>>79 struct list {
char name[20];
struct list *next; /* 自己参照構造体 */
};
で、構造体のポインタ *nextを作成しているのは分かるんです。
でも、それがどういう働きをして「次の構造体」に行っているのかがよく分からず……。
たとえばこんな感じ struct list { char name[20]; struct list *next; /* 自己参照構造体 */ }; int main() { list *listptr; listptr = (list *)malloc(sizeof(list); listptr->next = (list *)malloc(sizeof(list); listptr->next-next = NULL; return 0; }
一部ミス struct list { char name[20]; struct list *next; /* 自己参照構造体 */ }; int main() { list *listptr; listptr = (list *)malloc(sizeof(list); listptr->next = (list *)malloc(sizeof(list); listptr->next->next = NULL; return 0; }
あふーんorz またまたミス。ヘッダとかは自分でいれてね。 struct list { char name[20]; struct list *next; /* 自己参照構造体 */ }; int main() { list *listptr; listptr = (list *)malloc(sizeof(list)); listptr->next = (list *)malloc(sizeof(list)); listptr->next->next = NULL; return 0; }
84 :
74 :2008/07/09(水) 23:05:58
>>83 struct list {
char name[20];
struct list *next; /* 自己参照構造体 */
};
int main()
{
list *listptr;
listptr = (list *)malloc(sizeof(list));
/* mallocで確保したメモリの場所をlist型のlistptrに代入 */
listptr->next = (list *)malloc(sizeof(list));
/* listprtの中の*nextにmallocで確保したメモリの場所を代入 */
listptr->next->next = NULL;
/* listprtの中の*nextで指定されたlistptrの中の*nextにNULLを代入*/
return 0;
}
って理解でいいんでしょうか?
>>84 です。
リストを管理するポインターは例のような単純なリストでも2つは欲しいですかねえ・・・
listptrはリストをつないで置くだけのポインタ。
リストの入り口ですかね。
で、リストの最後を判別するために最後の構造体のnextにはNULLを入れます。
これはリストの決まりごとみたいな感じですね。
struct list { char name[20]; struct list *next; /* 自己参照構造体 */ }; int main() { list *listptr; //管理用 list *listwptr; //リストをたどる用 listptr = (list *)malloc(sizeof(list)); /* mallocで確保したメモリの場所をlist型のlistptrに代入 */ listptr->next = (list *)malloc(sizeof(list)); /* listprtの中の*nextにmallocで確保したメモリの場所を代入 */ listwptr = listptr->next; listwptr->next = NULL; /* listprtの中の*nextで指定されたlistptrの中の*nextにNULLを代入*/ return 0; }
初心者です。 Visual C++ 2008 Express EditionをDLし、プログラミングしてみたところ なぜかコンパイルできません。なぜでしょう・・・? ---------------------------------------------------------- プログラム 'c:\work\sample_console1\Debug\sample_console1.exe'を開始 できません。 アクセスが拒否されました。 ---------------------------------------------------------- OSはVistaで管理者権限で実行しています。
88 :
74 :2008/07/09(水) 23:44:41
>>86 むむむ、分からないorz
listptr = (list *)malloc(sizeof(list));
/* mallocで確保したメモリの場所をlist型のlistptrに代入 */
でlist型の関数にメモリの場所を渡してますよね?
このとき、struct listのchar name[20];は(今は説明のため省いてある部分だと思うのですが)どういう扱いになるんでしょうか?
>>88 一緒に確保されてる
構造体の定義が目次で、中身が本文で、本ごと手に入れるというか。
listptr->name とか listptr->name[0] とか
91 :
74 :2008/07/09(水) 23:59:05
int main() { list *listptr; //管理用 list *listwptr; //リストをたどる用 listptr = (list *)malloc(sizeof(list)); /* mallocで確保したメモリの場所をlist型のlistptrに代入 */ scanf("%c",&listptr->name); listptr->next = (list *)malloc(sizeof(list)); /* listprtの中の*nextにmallocで確保したメモリの場所を代入 */ listwptr = listptr->next; listwptr->next = NULL; /* listprtの中の*nextで指定されたlistptrの中の*nextにNULLを代入*/ return 0; } のような事をすれば、入力できると考えて大丈夫でしょうか?
>>91 領域をオーバーしないように十分な注意を払える環境であればそれでも。
そんなことないわ。 scanf("%s",listptr->name); だね
>>91 そういう使い方をするならとりあえず入力の情報を受けるだけのでっかい器
を別に用意して文字数の確認なんかをした上でmemcpyとかで
入れてあげたほうが良いかもしれないですね。
まず構造体をおさらいしてからの方がいいのかも? 入力処理に自信がもてず、構造体に自信がもてない状態でリストに進むと、 何か問題があったときにどこが問題なのかが分からなくなるかもよ
96 :
74 :2008/07/10(木) 00:18:47
了解です。 構造体あたりから復習してみます。 ありがとうございました!
int hoge[10000]; と言う配列を以下のように操作したいのですがいまひとつ効率のよい方法が思いつきません。 1.hogeには0以上の整数がランダムで入っている 2.0は空きと考え、hogeを添字0から順に走査して1以上の数であれば添字の小さい順に詰める (301200960890なら312968900000としたい) 出来る限り効率の良い方法はどのようになるのでしょうか?
それはCっていうより、アルゴリズムの話だからスレ違い
時間効率なんですが、すれ違いみたいなので去ります スレ汚し失礼しました
for(i=j=0; i<10000; i++) if(hoge[i]) hoge[j++] = hoge[i]; for(;j<10000; j++) hoge[j] = 0;
これでメモリ効率持ち出す奴ってどんなアルゴリズム考えたの?
103 :
デフォルトの名無しさん :2008/07/10(木) 01:25:10
それはCっていうより、アルゴリズムの話だからスレ違い warota
あげんなカス
あがっちゃうんだよ
最近のexe compなに使ってる?
XPに最適なCコンパイラをおしえて 今はbccつこうとる
vc++でいいんじゃないの? あれってGUI版も作れるし、コンソールのもできるでしょ?
>>107 統合開発環境を使うと関数のマニュアルやプロトタイプが簡単に見えたり
スペルチェックや変数名の補完もできたりするメリットはある
でも、現状それで何か不都合があるの?
>>107 Windows用ならやっぱり開発元の作ったVisualC++がいいだろう
せっかくだから俺はこのWindowsSDKを使うぜ!
112 :
デフォルトの名無しさん :2008/07/10(木) 13:49:50
入力は正の整数n. • 出力はn = a^2 となるような正の整数a が – 存在するときは上の式をみたすa の値. – 存在しないときは“ No ”. このプログラムの作り方を教えてください。お願いします。
>>112 正の整数を変数nに入力し、
nの平方根を求めて変数aに代入し、
変数aが整数ならそれを出力し、
そうでないなら"No"を出力する。
ように作ればいいとおもうよ。
114 :
デフォルトの名無しさん :2008/07/10(木) 14:19:22
>>113 ありがとうございます。
がんばってみます。
OSSである、expat-2.0.1のソースコードを読んでいるのですが、どうしても分からない部分があります。 elements.c内のstatic void XMLCALL startElement(void *userData, const XML_Char *name, const XML_Char **atts); この関数の引数XML_Char **attsのHeap領域がどこの関数で確保されているのかが分かりません。 構造体をchar **にキャストして使用している、と予想して探しているのですが、 ご存知でしたらご教授下さい。お願いします。
>>115 最初のポインターを配列に置き換えて考えてみたら?
自己管理がちゃんとできるならC++にたいした利点はありませんよね?
そのレスの意味する所が余りに広大そうで訳が分からん
>>116 レスありがとうございます。
最初のポインタを配列に置き換えて考える、というのはどういう意味でしょうか?
const XML_Char *atts[]
確かに自己管理ができていれば山本モナも番組降板になることもなかったわけで、 そう考えるとC++のことなんてほんとたいした問題ではない
>>117 ええ!?クラスとかデフォルト引数とか死ぬほど便利なのに・・・
>>120 XML_Char **attsは動的に複数個確保された構造体を指している、という事でしょうか?
CとC++て結局どっちが速いの?
>>123 main関数でコマンドラインに渡されたパラーメータを解析するとかやったことないの?
>>126 ポインタへのポインタってこと何だけど、これが分からないとなると...
char *へのポインタ、ですか? main引数のパラメーターの場合は二次元配列に使っている。と覚えています。
>>128 そこまで分かってるのに
試しに、コマンドラインに渡されたパラメータを表示することとかやってみたら?
130 :
デフォルトの名無しさん :2008/07/10(木) 18:01:18
自分の名前を大文字でYAMADA HANAKOのように入力し、小文字で出力せよ。 #include <stdio.h> #include <ctype.h> int main(void) { char ch; printf("Input > \n"); while( (ch=getchar()) != '\n' && ch != EOF ) { ch=tolower(ch); putchar(ch); } return 0; } でソースはわかったんですが、コンパイル後に Input > だけ出てきて何をどうすればいいのかわかりません・・・
入力してEnterだけど、人に頼るのはもうやめたほうがいい
132 :
デフォルトの名無しさん :2008/07/10(木) 18:03:59
入力してEnter押してもなぜか終了しちゃうんです。
Windows環境で、さらに出来上がった実行ファイルをダブルクリックして動かしたろ?
return 0; のまえに getcher(); でもいれとけ
135 :
デフォルトの名無しさん :2008/07/10(木) 18:06:35
はい、WindowsXPで 出来上がったexeを実行して動かしました。 違ったんでしょうか?
ごめん getchar
>>135 コマンドプロンプト開いてから実行すればよい
return 0; でmain()から抜けるんだから、終了しない方がおかしい
139 :
デフォルトの名無しさん :2008/07/10(木) 18:13:36
>>137 コマンドプロントから実行したらできました!
ありがとうございます!
>>129 すみません。レスが大分遅くなりました。
帰ってからパラメーターの解析をしようと思います。
早いか遅いかはプログラマ次第
出来上がったコードによるでしょ。 同じソースからコンパイルしたらほぼ同じものができると思うが。
double < long double < ? ?に相当するものってありますか? 小数点第60位までを表示したいです。
145 :
デフォルトの名無しさん :2008/07/10(木) 18:35:18
コンパイラではなく、C++の機能を使った場合だろ
146 :
デフォルトの名無しさん :2008/07/10(木) 18:36:08
多倍長ライブラリ
C++コンパイラで、なるべくCのコード書いて、必要最低限のC++機能を使うのが正解
char[] 型って1バイトの配列なのに2バイト文字を扱えるのはどうして? たとえば↓のようにやってもちゃんと文字が出力される #include <stdio.h> int main(){ char test[] = "いろはにほへと"; fprintf(stdout, test); return 0; }
>>149 printf("%d\n", sizeof(test));
とやってみるといいよ
>>149 SJISかな?
test[0] と test[1] の2つあわせて「い」だよ
>>151 川から海へと流れ出し、蒸発し雲になり、それは雨となり、いつかあなたの家の蛇口から出てくるでしょう
パラメーターの処理をしている部分がxmlwf.cにありました。 ここを解析していけばわかりますか?
外人の書く文章ってなんか笑えないんだけど面白い
それは翻訳のせいだ
>>154 解析するなら、もっと簡単な奴にした方がいいのでは?
>>157 レスありがとうございます。
例えばどのようなものがありますか?
>>158 本屋にいって入門書を立ち読みするとか?
>>159 elements.cを見ていて思ったのですが、
XML_ParserCreate
XML_SetUserData
XML_SetElementHandler
XML_Parse
XML_ParserFree
これらの関数はelements.c内で使われている関数ですが、
どのみちハンドラを呼び出すためには、上記五つの関数内でXML_Char **attsの部分を動的に確保する必要があると予測出来ます。
パラメーターから辿るのは今の私には無理があります。
XML_Char **attsを確保している部分の関数名を教えて頂きたいです。
>>160 配列が理解できてるなら、ポインタも理解できると思うんだけど
基本に立ち返って、自力で**の動作確認できるプログラムを作る方がいいと思うけど
>>161 どこでXML_Char **attsを確保する関数が呼び出されているのかが分からないのです。
なんか面倒そうな話してるなあと思ってソース拾ってきたんだが examples/elements.c の話してんの?
>>162 XML_Char **attsをパラメータにしてる関数を検索すればいいのでは?
何が分からないのか俺には理解できない。
>>163 そうです。
>>164 検索してもわからなかったのであなたに質問しています。
XML_Char **attsの部分を動的に確保している場所が分かりません。
167 :
163 :2008/07/10(木) 20:00:49
lib/xmlparse.c 2653は?
168 :
163 :2008/07/10(木) 20:04:01
ああ、関数名が欲しいのか。storeAtts
169 :
163 :2008/07/10(木) 20:13:52
まだ必要かどうかわからないが REALLOCマクロの定義は lib/xmlparse.c 552 で #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) 上記関数ポインタの設定はparserCreateでやってる。
>>167 レスありがとうございます。
ATTRIBUTE *temp;
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
なるほど、ATTRBUTE構造体をここで再確保しています。
parserCreate()内でも確保しているようですが、
一番気になるのは、
const char *name;
const char *vlauePtr;
const char *valueEnd;
をどこで確保しているのか、ここが分かりません。
>>168 今からstoreAtts();を見てみます。
>>169 そこは以前に見たものですが、先程再確認させて頂きました。
ありがとうございます。
申し訳ありません、言い忘れました。 const char *name; const char *vlauePtr; const char *valueEnd; はATTRBUTE構造体のメンバです。
あれ?それも場所を教えてっていってたの? storeAttsでその構造体を確保したんだからその後attsを使用してるとこ追ってけばすぐ見つかると思うけど。
と思ったけどパラメータでもらってたりするね。 たいして見てなくて申し訳ない
>>173 いえ、感謝しています。
今storeAtts()を見ています。
appAtts = (const XML_Char **)atts;これ以降で、appAttsが引数になっている関数はstoreAtts内に、
XmlGetAttributes()
getAttributeId()
storeAttributeValue()
poolStoreString()
addBinding()
上記の関数がありました。
私が気になったのは、名前からして、poolStoreString()です。
なので、/* String Pool */STRING_POOL;構造体を調べてみようと思います。
175 :
162 :2008/07/10(木) 21:10:51
なんか名前忘れてた。 とりあえず解析するならctagsというツールと、そのツールの出力ファイルを 活用可能なエディタを手に入れるといいと思う。 この関数の定義の場所へジャンプ、ということができるようになったりするよ。 あと、そもそも何で解析してるの?勉強?
177 :
162 :2008/07/10(木) 21:27:47
xmlを実際に解析させてみました。解析して分かった事は、 xmlparse.c内のpoolInit関数、poolCopyString関数、poolGrow関数、poolAppend関数、 poolStoreString関数、poolClear関数、poolDestroy関数が呼び出されていました。 ATTRBUTE構造体各メンバの動的確保はここで行われているのでは無いかと予想し、 今からここを重点的に調べていこうと思います。 皆様からの回答、本当にありがとうございます。 それでは、
ctagsのほかに、cscopeもあるでよ。 最近どこかで読んだけど、silentbobとかいうのもなかなかいいそうな。 まぁ、grepでしこしこ調べるのも、まぁアリといえばアリな気がするけど。
cで例外処理書くときはgoto文で書いたほうがいいですか?
私は、例外処理でもgotoは使わない。
setjmp, longjmp のペア?
gotoやjmp系は総て無視していたので、調べてみた。 準拠 setjmp() は C89, C99, POSIX.1-2001 で規定されている。 sigsetjmp() は POSIX.1-2001 で規定されている。 注意 POSIX は、 setjmp() がシグナルコンテキスト (signal context) を保存すべきかどうか を規定していない (System V では保存しない; 4.3BSD では保存する; 4.3BSD には シグナルコンテキストを保存しない関数 _setjmp もある)。シグナルマスクを保存したい のなら、 sigsetjmp() を使うこと。 setjmp() や sigsetjmp() を使うと、プログラムは理解 しづらく、保守しにくいものになる。別の方法が可能なら、それを使うべきである。 とあるね、やっぱり私は使わないか。C++の例外は使ってる。
>>180 いいとか悪いとかいうことはない
gotoの利点と欠点をよく考えた上で
必要かどうかを自分で判断すること
>>184 最初は使わないようにして、後々使うパターンを覚えたほうが有益だと思うがいかが?
rubyみたいに文字列をソースと見立てて実行したいんだけどどうしよう
>>186 無理。
無理やりな方法や、裏技的なやつはあるかもしれんけど、ふつーは無理。
使う関数を全部Defineとかすりゃ可能じゃね まぁ普通は絶対やらないけど
Cイタプリタを作れば勝つる?
↓こういう宣言した変数の領域って後から書きかえれないの? char s[] = "適当な文字列"; s[0] = 'A';
うん
書き換えてもいいけど、元の長さ以上の長さに書き換えるとバグになる
↑ごめん間違えた void Proc(char *string) { string[0] = 'A'; } Proc("椅子座りすぎて腰痛い"); ↑こんな感じの作ったらえらーでたんだけど、根本的にかきかえれないのかな
インタプリタでなきゃ無理だよな
void Proc(char * str) { str[0] = 'A'; } で動く、stringは変数名に出来ない。
>>191 書き換えられることが保証されていない
有体に言えば、やるべきでない
>stringは変数名に出来ない。 ( ゚д゚)
>>191 はchar型配列の初期化に文字列の書き方をしているだけだし、書き換え出来ると思うんだが
>>197 規格に有りますか? 有ったらどこか教えてください。
stringって予約語だっけ?
すまん、
>>194 は
>>191 だったんだな
void Proc(char *string)
{
string[0] = 'A';
}
Proc("椅子座りすぎて腰痛い");
は無理
void Proc(char *string)
{
string[0] = 'A';
}
char str[] = "椅子座りすぎて腰痛い"
Proc(str);
は可能
string は予約語ではなかった。 ミスだ
文字列リテラルには2種類の少し違った使いみちがある。配列の初期化指定子(chara[]の宣言で使うような)に使うときは、 その配列の各文字の初期値を指定する。その他の場所で使うときは、文字の名無しのstaticの配列となる。 このときは書き込み禁止のメモリーに保存されるかもしれない。だから無事に値を変更できない可能性がある。 式が必要な場所では、いつもと同じく(6章を参照のこと)配列はその場でポインターに変換される。 だから2番目の宣言はpを名無しの配列の最初の要素を指すように初期化する。 (古いコードをコンパイルするために、文字列を書き込み可能にするかどうかを制御するスイッチを持っているコンパイラーもある。) References: K&R2 Sec. 5.5 p. 104; ANSI Sec. 3.1.4, Sec. 3.5.7; ISO Sec. 6.1.4, Sec. 6.5.7; Rationale Sec. 3.1.4; H&S Sec. 2.7.4 pp. 31-2.
>>194 を実行すると、
Template.exe の 0x00403b56 でハンドルされていない例外が発生しました:
0xC0000005: 場所 0x004134e4 に書き込み中にアクセス違反が発生しました。
って出た。
これは問題なく動くぞ void Proc(char * str) { str[0] = 'A'; } void Proc2(char * string) { string[0] = 'B'; } int _tmain(int argc, _TCHAR* argv[]) { char bb[]="aaaaaaaaaaa"; Proc(bb); Proc2(bb); bb[0]='s'; return 0; }
環境は?
char str[] = "椅子座りすぎて腰痛い" ってのは、char型を21個分確保して、そこに初期値として "椅子座りすぎて腰痛い"で埋めてる。 char型配列ってのは要するに変数の集まりだから書き換えられる Proc("椅子座りすぎて腰痛い"); ってのは、"椅子座りすぎて腰痛い"という文字列を、プログラム起動時に読み取り専用の領域に確保して、 そこへのポインタをProcに送ってる。 Procの中で読み取り専用領域に代入しようとしてるから当然エラーが出る
>>194 みたいに書いたら変数領域どこに作られるんですか?
それか静的領域に作られるけど属性的にロックされるのかな・・・
>211 静的領域におかれる ロックされるかどうかは環境による
ロックされるにしてもされないにしても書き換えるべきではないな
それには賛成だが、エラーになる環境教えて。
エラーになったのはXPでコンパイラはVC++2008EE C++ソースとしてコンパイル#define _WIN32_WINNT 0x0500を指定
>>208 変数名が問題なのではない
>>203 の前者は、Proc()にWriteしちゃいけない領域を渡しているからNG
後者はWrite可能な領域(普通の配列)をProc()に渡しているからOKの違い
>>208 はWrite可能な領域を渡しているからOK
たとえばchar bb[]="aaaaaaaaaaa";の代わりにchar *bb="aaaaaaaaaaa";って書いたらだめ
>>216 申し訳ないが
>>208 のソースでもエラーですか?
書き忘れ VC++2005 Win2000
ちなみになんで書き変えようと思ったのかというと #define tostrcpy(dist, str) _tostrcpy(dist, #str) char *_tostrcpy(char *dist, const char *str) //文字列両端の\"を削除する関数 { strcpy(dist, str + 1); size_t nLen = strlen(dist); dist[nLen - 1] = 0; return dist; } なんかの関数(tostrcpy("C:\Window\memochou.exe")); ↑これがめんどくさいから横着して入力場所を直接書き変えたかったってわけでs いちいちパスの\を\\にするのめんどくさいという理由によって。。。
いちいちdist指定してdistにコピーするのがめんどくさいから か
char aa[]="C:\Window\memochou.exe"; なんかの関数(tostrcpy(aa)); 2行にすればいけるが…
>>223 まぁそうなんだけど、1行でできたらいいなぁって思った
ちなみに
#define ___(x) #x
___("C:\Window\memochou.exe"); //正常にコンパイル
___(C:\Window\memochou.exe); //エスケープシーケンスがどうのってエラー
がでるんですよね・・
225 :
デフォルトの名無しさん :2008/07/12(土) 01:45:05
変数を宣言と同時に初期化する時、 int a = b = c = 100; とするとエラーになるのは何故ですか? 単なる代入ならばこの書き方で通るのに、宣言時だと何が変わるのでしょうか。
あ、当然か。ではもうひとつ質問がっ。 char *___strchr(const char *str, int c) { //strchrの中身は↓こうなってるらしいですが、 c = (char)c; while (*str && *str != c) ++str; if (*str == c) return (char *)str; return NULL; } ___strchrを使うより普通にstrchr使ったほうが1倍〜10倍以上、 速度が元物のstrchrのほうが速いんですよね。 strchrの本当の中身ってアセンブリか何かで書かれてるんですか?
int a = b = c = 100; bとcの宣言はどこにあるんだよ
>>227 ああ、この状態だと宣言せずに式の中で使っていることになるのですね。
わかりました、ありがとうございます。
>あ、当然か。 この時点ではどんな原因だと考えてたんだ?
windowsプログラムなんですが、 画像のある特定の範囲だけの色を変えるのってどうすればいいのでしょうか? テンプレートマッチングでマッチングした部分の色を変えられず苦労しています。。
int A; void func(void) { int B; for (10000000回繰り返し) A = 9999; for (10000000回繰り返し) B = 9999; } 変数AとBでアクセス速度に違いがあるかどうか教えてください。
>>235 システムによって違うので、実際に測定しないとわからない。
↑というのが前提で。
最適化がまったくなかったら、グローバル変数のほうが速い場合がおおいような気がするけど、
いまどきローカル変数をレジスタに割り当てるとか当たり前だからBのほうが速いかもしれない。
>>236 今時の最適化は、ループ自体が無くなる、は置いといて。
グローバルも、最適化ではレジスタ割り当ても有る。
優先順位としてはBの方が高いと思うけどね。
ではレジスター割り当てが出来ない場合は、Aがじか引き
Bはスタックエリアのインデックス引きでBが遅いかもしれない。
プログラムのアセンブルリストを見るのが一番速い
インデックスレジスタでメモリアクセスのほうが速いCPUもあるな
アセンブラみるより計測するほうが早いよ。
240 :
235 :2008/07/12(土) 16:13:02
>>236 なるほど。自分の環境で計ると、
//void msgbox(char *string, char *title = "msgbox") { MessageBox(NULL, string, title, NULL); }
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
LARGE_INTEGER pcBef, pcAft;
LONGLONG ll1, ll2;
QueryPerformanceCounter(&pcBef);
fori (1000000) A = 9999;
QueryPerformanceCounter(&pcAft);
ll1 = pcAft.QuadPart - pcBef.QuadPart;
QueryPerformanceCounter(&pcBef);
fori (1000000) B = 9999;
QueryPerformanceCounter(&pcAft);
ll2 = pcAft.QuadPart - pcBef.QuadPart;
sprintf(g_, "%f", (double)ll1 / (double)Frequency.QuadPart);
msgbox(g_);
sprintf(g_, "%f", (double)ll2 / (double)Frequency.QuadPart);
msgbox(g_);
測定の仕方ってこれであってます?
両方ともかかる時間は0.0024秒付近でした。
最適化ありだとほとんど変わらないぽいですね。
241 :
235 :2008/07/12(土) 16:43:21
↑すみませんA=9999の部分を削っても0.024秒でした… 代入による負荷は限りなく低くて無視できるようですね…
>>240 大体の目安にはなるかもしれないけどソース埋め込みだとレジスタに置かれてたのがスタックに置かれたりして厳密な測定値は得られない
デバッガにブレークポイントからブレークポイントまでの時間を測る機能はないの?
え、そんな機能あるんですか? VC2008だけどあるかなぁ・・・
CL /FAsc オプションでアセンブリリストださないとなんとも。 意味のないループは最適化されやすい。
最適化なしだと違いはこれだけ命令コード長が3バイト異なるがクロックは同じ。 命令の並列化とかメモリキャッシュの具合で差が出るかもしれない。 c7 05 00 00 00 00 0f 27 00 00 mov DWORD PTR ?A@@3HA, 9999 ; A, 0000270fH c7 45 fc 0f 27 00 00 mov DWORD PTR _B$[ebp], 9999 ; 0000270fH
最適化ありの場合は既に意味のないループも代入も消えてなくなってしまった。 ; 7 : for (int i = 0; i <10000000; i++) A = 9999; mov DWORD PTR ?A@@3HA, 9999 ; A, 0000270fH ; 8 : for (int i = 0; i <10000000; i++) B = 9999; ; 9 : } ret 0
基本はCで、C++の最低限の機能をつかうのがいいとは言うけど、具体的にC++のどこが使えると言えるの?
STLとか
>>243 ごめん、242は組み込みおじさんなんで自分の感覚で書いてしまった
MSDNのヘルプ見たけどVCではコード埋め込むのが一般的なのかな?
プロファイラが別途必要なのか、VCは疎いのでわからない
適当なとこにint 3でも埋め込んどけばいいんじゃね
251 :
デフォルトの名無しさん :2008/07/12(土) 18:48:16
typedef struct STRUCT_IMAGE{ int width, height; int depth; void* pixels; } ImageData; という構造体の宣言があってこの後のプログラムで ImageData が型の名前として使われているようなんですがどういうことですか? 型として使うなら STRUCT_IMAGE だと思うんですが。
struct STRUCT_IMAGE img; って書くのめんどくさいじゃん?
254 :
デフォルトの名無しさん :2008/07/12(土) 19:07:44
>>235 volatileつけてみたら変わるかな?
ちょっと稚拙な質問かもしれませんが行き詰まったのでお願いします。 void main(){ int i; int a[10]; for(i=0;i<10;i++){ scanf("%d",&a[i]); if(入力側で改行があったら) break; } } scanfで、次の要素に移るときは基本的にスペース、もし改行があったらそこでループを抜けるプログラムを書きたいのですが、 breakの条件文がわかりません・・・。 もし、適当な条件文があるなら教えていただけないでしょうか。
a[i] == '\n'
%dで改行を拾えたっけ?
素早い回答ありがとうございます。
ん〜今やってみましたが、改行してもscanfが終了しませんでした…
俺がscanfの仕様をよくわかってないのもあるかもしれません。
ちょっと
>>256 のだと語弊があることを懸念して、
「ループを利用して配列に数字を入力中、改行するとすぐさまそこで文字入力を終了する」
ということです。
…ひょっとするととんだ見当違いなプログラムを書いてしまったかも…
何も入力せずにEnter押したら終了、みたいなのはscanfじゃ無理だと思うけど。
終了するときは数値以外の入力をしてもらうって仕様にすれば、scanf()のリターン値をチェックすれば対応できるけど。
なるほど、やはりエンターでは難しいですか。 わかりました。終わるときは何か他の文字を入力してもらうことにします。 ありがとうございました!
263 :
デフォルトの名無しさん :2008/07/12(土) 22:48:11
c = fgetc(fp) でcに代入するのはfpのファイルのどこのバイトですか?
>>263 オープンした直後なら最初のバイト。
二回目の実行なら二つ目のバイト。
>>263 一回目は先頭
二回目は2バイト目
三回目は3バイト目
・・・
現在地と言ったほうがいいのでは
267 :
デフォルトの名無しさん :2008/07/12(土) 23:09:44
1バイト取得して、1バイト進める
269 :
デフォルトの名無しさん :2008/07/12(土) 23:20:53
>>268 分かりました。
ありがとうございました。
すごく初歩的な内容ですがわからないことがあるんです char initial[15]; char name[15]; printf("苗字を記入\n"); scanf("%s",&initial); printf("名前を記入\n"); scanf("%s",&name); で、苗字と名前を記入するプログラムの練習をしてるのですが このプログラムだと苗字、名前15文字までしか入れることができません。 で、if else をつかって16文字以上入力した場合には 「名前が長すぎる」とprintfで持ってきたいのですが、どうしてもできません。 なにかヒントみたいなものでも良いのでどなたか助言いただけないでしょうか?
strlen関数で文字数を取得するとか
char initial[100]; char name[100]; while(true) { printf("苗字を記入\n"); scanf("%s",&initial); if(strlen(initial)>0 && strlen(initial)<15) break; printf("入力が長すぎます\n"); } while(true) { printf("名前を記入\n"); scanf("%s",&name); if(strlen(name)>0 && strlen(name)<15) break; printf("入力が長すぎます\n"); }
しょうもない質問ですみません。 while(0) { printf("*"); } このプログラムを実行したとき*は幾つ表示されるかが分かりません 実行してみたんですがエラーが出てしまいます orz
エラー???? 何も表示されないだけかな
>>276 ありがとうございますm(__)m
エラーが出ないように何回かいろんなところいじってみますorz
ソース上げれば添削するよ
×scanf("%s",&initial); ○scanf("%s",initial);
initialと&initialと&initial[0]は同じポインタになるな
>>279-280 今、試行繰り返してますが
どちらでも動くみたいです。
>>273 のおかげでなんとかエラーなしで動くようになったので
これからプログラムの流れの解読開始します
けどscanf("%s",&initial);って書かれると 分かってるのか?って思う
>>280-281 ならない。
配列に&演算子を作用させたときに得られるポインタは配列へのポインタであって、
配列の先頭要素へのポインタではない。
memset() などでは、配列の先頭要素へのポインタを与えても、配列へのポインタを与えても、正当に動く。
なぜなら memset() の引数が void * と定義されているために、コンパイラが暗黙に適切な型変換を行うからである。
一方、可変個数の引数を取る printf() や scanf() では、そのような暗黙の変換は行われない。
scanf() で %s を指定した場合に与えるポインタは char へのポインタでなければならない。
ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても
(渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
しかしそれは規格が保証した動作ではない。
ついでに考えられることとして、文字列を指させているポインタを配列だと勘違いして (あるいはつい同一視してしまって)&演算子をつけて printf() や scanf() に渡してしまうことがある。 これはどんなマシンであっても、たぶん動かない。
>>285 printf("name=0x%x &name=0x%x\n", name, &name);
で、両方とも同じ値なのはなぜ?
>>287 そのようにしたとき、&nameが配列の参照からポインタに成り下がるため、先頭アドレスが表示される
>287 |ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても |(渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
>>288 違うw
配列のアドレスと配列の先頭アドレスが一致するからだ。
どうでもいいことだが、%pじゃね?
>>290 &nameと配列の参照を取得した時点で、それは先頭要素を指すポインタに変わると思ってたが、違うのかな
nameは配列全体で、ただしすぐ先頭要素へのポインタになる &nameは配列全体へのポインタになる &name[0]はまずname[0]が結合し次に&だから先頭要素へのポインタから0番目の要素へのポインタ=先頭要素へのポインタ たいてーの処理系では値としてはまったく同じものでコンパイラが型チェックすることがあるだけ でももちろんそうでない処理系もあるかもしれないということになる(C規格の上では) %pに渡すポインタも、void*にキャストする必要があるかどうかは処理系定義じゃなかったかな
char a[] = "abc"; というのがあって、aは0x10000とする。 aは当然0x10000なのだが、&aは? &をアドレスを求める演算子と考えれば、aはもともとアドレスなので&aはaの値をそのまま返す。 ということではないのかな?
>>285 > ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても
> (渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
> しかしそれは規格が保証した動作ではない。
規格上は指す型によってポインタのサイズや内部表現が違ってもよいのですね
指すのが構造体の場合も、指す構造体によって
やはりサイズや内部表現が異なる可能性がありますでしょうか・・・?
継承っぽい動作の実装で構造体へのポインタを異なる構造体へのポインタに
キャストしてるもので。
char *p; p が 0x10000とした場合、 &pはpがもともとアドレスにもかかわらず、pと&pは異なる値になるよ
>>295 ちがいます。
aは&演算子のオペランドでない場合は&aになる。
>>294 > すべてのCコンパイラで配列への(キャストのない)参照はポインターを産み出す。このポインターはTへのポインターで配列の最初の要素を指す
これについてはどう思いますかね
>>295 逆じゃね?
&a は配列aのアドレスを返す
aは配列だが添え字とか&がなければ配列のアドレスを返す
>>295 違うよ
aはもともとはアドレスじゃなくて識別子つまり配列そのもの
いくつかの例外(&aを含む)を除いてアドレスに変換されるけど
あとアドレス演算子とは呼ばれているけど、実際に&演算子が生み出すのはポインタ
Cのポインタは「アドレス」と「型」が一緒になった概念
ほとんどのコンパイラは前者だけを変数に保存してコンパイラだけが後者を管理するから
出力すれば同じものに見えるけどね
>>296 構造体レベルだとたぶん変わらない
関数ポインタになると変わってくる
>これについてはどう思いますかね どう思いますかねって何もおかしくないでしょ そこには書いてない例外の部分もちゃんと含めてだけど
>>302 さんくす
そうだよな、構造体は仮宣言でもポインタで取り回せるし
(それも規格に合ってるのか知らんけど)
>>304 キャストするぶんにはそのへんコンパイラがちゃんとやってくれることになっている
306 :
デフォルトの名無しさん :2008/07/13(日) 12:25:41
>>301 じゃあ、
char str[10];
scanf("%s",&str);
って書いた方が本来の意味として正しいってこと?
型が違う
何がどう違うの
int dm[10]; int *p = dm; int (*p2)[10] = &dm;
俺が無難な指針を出してやろう。 &配列名 は当面使わなくてOK、な。
ウィンドウを表示してそこにボタンを表示したいんですけど、ボタンを表示する方法がわかりません。 だれかボタンを表示する方法を教えて下さい。
314 :
311 :2008/07/13(日) 16:50:34
今どきチャートなんて作らんよ
318 :
316 :2008/07/14(月) 14:47:43
オブジェクト指向の言語ならUMLだとかいろいろあるが C言語のように単なる構造化の場合どうやるんだろ? 古典的なフローだとどうもGOTO使ってるぽくていやなんだが
>>318 古典的フローチャートにもループ記述子が存在しているからそれを使えばOK。
つーか、そもそも構造をブロック化するだけじゃないかと思うが。
>>318 右側の構造化チャートならgoto使うイメージ無いだろ。
system("command");の出力結果を得たいのですがどうしたらよいでしょうか 自分としては一つの方法として「標準出力をフックする」というのは思いついたのですが 難しそうなので半ば諦めかけています。 何か方法はありますか
>>322 凄い、出来ました。
ありがとうございます
#include <stdio.h>
int main()
{
FILE *fp;
char buf[256];
fp = popen("ls", "r");
while(!feof(fp))
printf("%s", fgets(buf, 256, fp));
return 0;
}
>>321 大抵の環境でpopen()が使えると思う。
>>324 そうなんですか
windowsでも出来るんですね
cygwinのdllでも同封してun*xコマンドを駆使しつつ
両方で活用できるソフトを作る事も出来そうですね…
ありがとうございます
>>325 VisualStudioなら_popen()かな。
>>326 そうなんですか
ありがたいですm(_ _)m
char buf[256]みたいな配列の 10〜100番の要素を5〜95のように同サイズで重なる領域にコピーしたいんですが こういう場合は一旦どこかに変数を保存しないと実現できないんでしょうか?
コピーする順番がコントロールできるなら、そのままコピーすればいい
>>330 おお、こんな便利な関数があるのですね
ありがとうございました
>>329 C/C++の宿題を片付けます 111代目
http://pc11.2ch.net/test/read.cgi/tech/1214563642/136 の一部
136 名前:デフォルトの名無しさん[sage] 投稿日:2008/06/29(日) 10:13:37
void cmemmove(char*dest ,char*src, int length){
int i;
if(dest<src) for(i=0;i<length;i++) dest[i]=src[i];
if(dest>src) for(i=length-1;i>=0;i--) dest[i]=src[i];
}
リスト構造がむずいです。どういうふうに捉えたらいいのか・・。
>>334 今後どうしてもC++に移行したくない理由があるわけでないのなら、
今は放置しておいてC++でリスト構造を勉強することをお勧めします。
336 :
デフォルトの名無しさん :2008/07/14(月) 23:18:53
stl
>>334 人が手をつないでる感じでどうですかね。
隣の人の隣の人、みたいな。
>>337 ノードがあって
つながり方は色々
急を要するのでなければ
ノードの部分だけ分かってれば今はいいんじゃないかな
>335の言う通り、他の事も分かって改めてやってみるとぐんと分かったりするし
よーするにだな。 1つ前にいる人の位置と、1つ後ろにいる人の位置を、自分がデータとして持っているわけだ。 そういう人達が連なってできるのがリスト構造。 1つ前の人がいなくなったら、さらに一つ前の人の位置に書き換えればいい。 だから、構造の途中での削除や挿入が簡単に実現できる。
struct node *p; でpが構造体のポインタ?宣言して、 p = (struct node *)malloc(sizeof(LISTEL)); でメモリ確保した時って、確保するごとに新しくpができるのかな。 意味不明だったらすみません。
任意の紙っぺらにセロテープで糸を貼り付ける その糸の反対側は、必ず他の紙に貼り付けるか オワリの印に五円玉を結びつける
データは緑色のヘビで、 各ヘビは目の前のヘビのしっぽにかぶりついてるんだ。(単方向連結リスト) 最終的には大きな輪っかになってる。 その中に一つだけ、赤いヘビが混ざっていて、 一番目のヘビって言ったら、その赤いヘビから尻尾の方へ何番目って数えるんだ。
>>340 新しくpは出来ますよ
ただ古い方のpをfreeしないとメモリリークですね
int main()
{
int i;
struct node *p = NULL;
for (i=0; i < 10; i++, p=(struct node*)malloc(sizeof(struct node)))
{ printf("%p\n", p); free(p);}
return 0;
}
と表示度にメモリ番地が変わってるのが分かるでしょう
あえて省いたのかも知れないけど
struct node *p と書かなくて node_t *p でも分かる人は分かるから
node_t は typedef struct node node_t; ね
最後無駄なこと言ってるようにしか見えない
>>struct node *p = NULL; NULLいれるのは初期化ってことですか?
入れた値を使っていないということ
使ってる 使ってるよ あまり感心する使い方じゃないが
ループの1回目でfree(NULL)になるね
free(NULL)は全然合法だから。
ide使ってる?viで十分だよね
時代に取り残されてはいるがそう思い込めれば少しは楽になるだろうね
Web上の画像を取得しようと思ったら、これをぐぐれリストみたいなの 教えてください。
>>354 ぐぐる前に自分が使っているOSとプログラミング言語のことを知れ。
>>354 「著作権」、「パブリックドメイン」、「Creative Commons」、「ライセンス」、「無断転載禁止」、「Web魚拓」、「引用」、「違法ダウンロード」、「海外サーバ」
こういうのが知りたいの?
atoiってありますよね、あれのatohとかってないのかな?
360 :
358 :2008/07/15(火) 19:56:28
hex
atohって言い方は変ですね atoiで10進数の文字列が与えられるとintに変換しますけど 16進数の文字列をintでも何でもいいので数値かしたいだけなんですけどね・・・
sscanf
>>362 それは書式指定して16進数の文字列を一度10進数文字列に変換したあと
atoiってことでOK?
>>363 直接変換となるとこれっぽいですね。
ありがとうございました。
>>364 sscanf("abcd", "%x", &num);
>>365 あーorz
すみません、そうですね。
関数の仕様を読み間違えてました。
失礼しましたorz
いやいやいや、10進数表記や16進数表記は、文字通り「表現のしかた」の話だよ。 変数に格納するデータは10進でも16進でも同じでしょ。
質問です *str='A'; str[1]='B'; str[2]='C'; str[3]='D'; str[4]='N'; str[5]='V'; str[6]='X'; str[7]='Y'; str[8]='Z'; str[9]='\0'; while(str[i]!='\0'){ if(str[i]>='Y'||str[i]>='y'||str[i]>='7'){ str[i]-=3; printf("-3しました\n"); }else{ str[i]+=3; printf("+3しました\n");} ++i;} printf("%s\n",str); まず、strというchar型でサイズ10の配列をつくりそれぞれの要素にA-Zの適当な文字を入れて、最後に終端文字を入れます 次に終端文字が来るまでY(0x59)以上もしくは y(0x79)以上もしくは7(0x37)以上なら配列要素を-3してそれ以外なら+3するプログラムを組みましたが、 数字(0x30-0x39)以外の判定が上手くいきません 何故でしょうか。
>>368 数字以外の判定がうまく行かない、の意図するところがよくわからないけど、
0x37以上っていうのはa〜zもA〜Zも含んじゃうから期待通りの動きをしないのでは?
y-z Y-Z 7-9のときに減らしたいのならそのように書かないと駄目です。
*strとstr[1]〜が混在してると気持ち悪いなw
>>368 そのリストを見た印象では、まともに動くものと思えない。
リストの全体を出すべき。
>>371 だって、書くものは少しでも省略したいじゃん?
*str
と
str[0]じゃ2文字も違うんだぜ?
>>373 そうやって可読性を下げて、後から自分自身で後悔する
こういう癖は、今のうちに虚勢した方が良い
>>374 掘った穴に落ちてこそ意味が分かる
他人が穴ぼこだらけにしたものが回ってくるのは我慢ならんがw
>>374 そうなのか
俺はこっちで慣れちゃってるんだが・・・
まぁ、TPOで使い分けるよ
>>368 最初の配列は以下のように書いたほうがもっと少なくて済む上にわかりやすい。
str[] = "ABCDNVXYZ";
あとは
>>369 に同じ。
虚勢ってなんだ? 去勢か矯正の間違いか?
1. きょせい【虚勢】別ウィンドウで表示 ⇒関連語みえ【見え・見栄】
難読プログラミングの世界があるかもしれない。(見たくないし書きたくないが
プログラミング診断室の出番だな
他人の忠告を素直に受け入れられないのはマとしてより人として血管
どうみても初心者なのでそのうちわかるでしょ
俺はDQNすぎたのか、もう誰も忠告してくれなくなった... orz
晒してある範囲で判断する限り while よりは for(i=0;str[i]!='\0';i++) の方が楽
>>382 あの人性格悪そうだよね。でも考え方は共感できる。
ラクすることを考えろ。書かなければバグも入らない。まさにその通りと思う。
388 :
デフォルトの名無しさん :2008/07/15(火) 23:50:49
どうも、少し前にExpatについて質問した者ですが、 xmlparse.c2622行目のstoreAtts()関数について、どうしても分からない事があったので質問しに来ました。 2665行目付近にappAtts = (const XML_Char **)atts;という式があります。 これは、ATTRBUTE構造体を(const char **)にキャストして、appAttsに添え字を使ってATTRBUTE構造体の各メンバにアクセス出来るようにしていると思いますが、そうであるなら typedef struct { const char *name; const char *valuePtr; const char *valueEnd; char normalized; } ATTRIBUTE; appAtts[0]はname、appAtts[1]はvaluePtr、appAtts[2]はvaluePtr、appAtts[3]はnormalizedを指していると考えているのですが、 element.cのstartElementハンドラの第三引数、const char **attsに属性名及び属性値がベクタ形式で保持されている訳ですが、 保持している場合、const char *name,const char *valuePtr,const char *valueEnd、この三つにしか保持出来ないと思うのです、 前述のappAtts = (const XML_Char **)attsはATTRBUTE構造体の各メンバに添え字を使いアクセスするためにキャストして使用している、という考え方に基づき考えていった場合 startElementハンドラ内でatts[3]にアクセスした場合は、ATTRBUTE構造体のnormalizedを指すと考えられます。 しかし、normalizedは1バイトのchar型でありポインタではありません。1バイトの領域しか指さない事になります。 では、第三引数であるconst char **atts、は一体どこを指しているのか、 かれこれ二日行き詰っています。ご教授お願いします。
前見たときも思ったけどマニュアルに書いてないのか?
マニュアル………… それはどこにありますか?
>>387 もう すこし にほんご を べんきょう したら いかが ですか。
392 :
デフォルトの名無しさん :2008/07/16(水) 00:43:49
>>388 前の質問内容が理解できていないので恐縮だけど・・・
appAttsって、テンポラリのローカル変数な予感。
確認したいんだけど、appAtts[3]って、「element.cのstartElementハンドラ」で使用されているの?
使用されていなければ、無問題なわけで。
startElementの中でどう処理してるかと startElement呼んでる場所でどう処理してるかを 見てみるしかないんじゃないの
>>388 なんでexpatのソースなんて読んでいるんだっけ?
初心者が勉強のために読むにはちょっと荷が重い気が。
あと、特定のソフトの特定の部分の挙動なんて質問しても、その部分を
読んだことがある人しか答えられないことを理解しよう。ここを読んで
いる人でexpatのソースを読んだことがある人がいる確率はものすごく低
い。
fooとかbarとかいったい何者なの?
ざっくり読んでいったんだけど、 attsが読まれて消費される速度 > appAttsが書きつぶす速度 という前提で、メモリ領域を流用しているんじゃないのかな? atts自体はルーチンの後の方では参照しないし。 だから、appAttsがATTRBUTEの配列(atts)を無理矢理キャストして 使用しているんじゃなくて、reallocで分捕ってきたメモリ領域を、 attsとappAttsが共用していると考えるべきじゃないのかな。
>>395 申込書とかの記入例に書いてある○○太郎とかと同じようなもん。
名前自体に意味はないという意味を持っている。
>>392 確かにローカル変数ですが、この変数はstoreAtts()関数内で属性名:属性値の保持のために使われていると思います。
appAttsを(const XML_Char **)atts;とした時点で、appAtts(0から3までの添え字)でATTRBUTE構造体四つのメンバへのアクセスをしているであれば、
2729行目のappAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,atts[i].valueEnd);
添え字であるattIndexが3の時はchar normalizedを指している事になり、ポインタでなく、1バイトのchar型に属性名:属性値の保持は無理です。
しかし、2729行目のappAtts[attIndex]の添え字が3であった場合も値は格納されていて、printf()関数で属性値の表示も出来ました。。
この事からappAtts[3]はATTRBUTE構造体のchar normalizedを指していない事となります。
ではappAtts[3]はどこを指しているのか、これが分からないのです。
>>393 attsはATTRBUTE構造体を指し示すマクロでしかありません。
ハンドラが呼び出されているのはxmlparse.c2148行目、docontent()関数からです。
startElementHandler(handlerArg, tag->name.str,(const XML_Char **)atts);
ハンドラでは、attsを参照するだけなのでどのように属性名:属性値を格納しているかを調べないと解決出来ないと思います。
>>394 読んでいる理由は勉強のためです。
>>396 今から共有について調べてみます。
もうはっきり言っていいか? 入門編の範疇じゃねぇし ことによるとCの話でもねぇよ
>>396 が言ってるとおり、ATTRBUTE構造体の4ブロック目
(たぶんnormalizedのあとに3バイトつめものがされて4バイトなんだろう)を
const char *用の領域として流用してるんだと思う
というかここに出てる材料ではそれぐらいしか考えられない
>>396 つまり、ATTRBUTE構造体(アライメント:32bit=4byteの区切り)16byteあり、appAtts = (const XML_Char **)atts;にキャストする事で、
属性値が保持されている4byteのアドレスをchar normalizedにも格納している、という事でしょうか?
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); atts = temp; ってなくらいだからattsはATTRIBUTEの配列なんでないの?
おまえ人にソース読むことを強要する質問はやめろ
405 :
402 :2008/07/16(水) 11:53:20
>401 ×char normalizedにも格納している ○char normalizedを含む4バイトのフィールドにも格納している だろ
勉強のために読んでいるっていったな? それを読むことを薦めたやつに聞け
前回からどこが成長したんだ? メモリ管理周りは把握できた?
expatのソース読む前にまだもっと基礎を勉強すべき。 そして質問の仕方と日本語も勉強すべき。 かれこれ二日行き詰っている間に基礎を勉強していたら違う人生を歩めてたはず。
>>407 なるほど、把握しました。
>>408 薦められた訳ではありません。
>>410 昔は多趣味だったんですよ、私
アリエナイ理科の教科書や仏教、発電、エンジンなんかの書籍を読みあさっていましたし
カメラを分解して感電したり小さいながらもドライアイスを液化したりスターリングエンジンを作ったり、とまぁいろいろやっていました
注射器取り寄せるにも薬局でエタノール買うにも金がいります。中学生には無理な趣味だったんです。
解答ありがとうございます。
それでは、
なんだ中学生か。ごめん言い過ぎた。勉強頑張ってね。
>>411 なぜ基礎を学んでからの方が良いという提言をスルーするの?
>>411 自分で好きなことを見つけて学ぶのもいいけどね、
学校や親から「与えられる知識」は基礎作りにはもっと重要。
これは小さいうちしかできない乃至やらないから大事にしたほうがいいよ。
本当に伸びたければ、趣味に限ってないで何でもやらないと。
おいおい、昔中学生だったんだろw
416 :
デフォルトの名無しさん :2008/07/16(水) 16:03:30
そりゃキロメートルのKmだろ
フルマラソンは 42.195000Km かな
419 :
デフォルトの名無しさん :2008/07/16(水) 16:15:21
ですよね
>>418 どうも km42.195?変だなぁと気になって気になって
%f`b
バiタ
>>419 km42.195
ないわぁw 倒置法ないわぁw
構造体のメンバの宣言の順番とメンバのアドレスの順番は一致することが保障されているのでしょうか? もし保障されていないのなら自分で並び方を固定したいのですがどんな方法がありますか?
424 :
デフォルトの名無しさん :2008/07/16(水) 20:54:27
一致する
>>423 一致するが一つ注意がある。
コンパイルする環境によってだけどCPUがアクセスしやすいバイト単位になるように
ダミーが入るケースがあって構造体サイズが増えることがある。
ずれるのも構造体内部のメンバの位置が数バイトだけだけどね。
426 :
423 :2008/07/16(水) 21:03:24
>>424 ,425
ありがとうございます
あるメンバからあるメンバまでをまとめてコピーしたかったので
ダミーの混入は両端のアドレスから解決できそうです
ひとつひとつコピーするのが正統なやり方だと思う
428 :
デフォルトの名無しさん :2008/07/16(水) 21:16:40
標準で全体を代入できた気はする
429 :
デフォルトの名無しさん :2008/07/16(水) 21:18:08
板違いかもしれませんが質問させて下さい。 コンパイラはlsic86の試食版を使っているのですが、 コマンドプロンプトでコンパイルして実行すると日本語部分が文字化けします。 OSはvista。おそらくIMEのverに対応してないのかどうかって所なんでしょうけど。。 何か他にお勧めのコンパイラありませんか?? やっぱりvisualcですか?? cに適した環境をご教授頂ければ非常に助かります。
>>428 構造体間の代入はできるよ。
でも部分的に代入したくない場合は個別になるかなあ。
あとはコピーしたくない部分とコピーする部分を分けることが可能なら
構造体を2段で定義してコピーしたい部分+したくない部分としてその二つをまとめるだけの構造体
とすればOkだけどね
431 :
デフォルトの名無しさん :2008/07/16(水) 21:22:02
lsicの試食版使うなよ マイクロソフトVC++2008かBCC developer
double a = 36.3343; int b = 5; int c = 4; int d; d = a * b / c; っていうようなdoubleとintを組み合わせて計算した場合の 答えはdoubleでしょうか?intでしょうか?
double
>>432 まずa * bでbがdoubleに格上げされて計算の結果doubleの値が生まれる
次に/ cでcもdoubleに格上げされてdoubleの値が生まれる
最後にそれをdに代入すると小数点以下が棄てられてintの値になる
>>429 ソケットの扱いとか面倒だけどBorland C/C++
bcc32.exeとかbcc55で探せばあるかもね
WinXP & VC2008Expressでコンソールベースのゲームを作っています。 キャラデータを含む構造体をバイナリファイルとして保存するとき、 チート対策のため単純にそのまま記録するんじゃなくて暗号化したいのですが、いい方法ありませんか?
>>437 乱数seedをファイルの先頭に保存
あとは乱数とデータのxorを保存
適当なアーカイバで圧縮してヘッダをファイル末尾に回す
439 :
437 :2008/07/16(水) 23:09:47
>>438 おお、すばやい回答ありがとう。
複合化のときは、ファイルに保存されてるseedでsrand()すればよさそうですね。試してみます。
440 :
437 :2008/07/16(水) 23:11:19
ん?違うな。ファイルに保存されてるseedでXORですね。
>>440 自分が解析しにくいと思う方法でやればどっちでもいいよ
どれだけ対策をしてもできる人にはできる
とりあえずチェックサムをいれておいて不正なデータは拒否
442 :
デフォルトの名無しさん :2008/07/17(木) 00:44:29
コンパイルして実行すると コマンドプロンプトで日本語だけが文字化けするんですけど これってどうしたら直るんだ・・・。 vistaじゃCはできねーのか?? 誰か助けてー。。。Borland C/C++とlsic86の試食版を使ってますが どっちも文字化けしまっす。
>>442 Vistaじゃないから分からないけど
ソースコードの保存形式が関わってたりして
ソースの文字コード弄ってみたらいかが
bccならオプションでtWUとかあったような
445 :
デフォルトの名無しさん :2008/07/17(木) 08:45:16
str_repeatを使わずに文字列を一定回数繰り返して返すにはどうしたらいいのでしょうか?
int p; printf("%p\n", &p); getchar(); コンソールを同じ方法で2つ起動してそれぞれ実行するとアドレスが同じになるそうですが、ならないのですが、 コンパイラはgccでdebian etchです 仮想アドレス空間がうんたらかんたらって本に書いてあったんですけど、 ポインタ完全制覇って本です
447 :
デフォルトの名無しさん :2008/07/17(木) 10:23:18
>>442 コマンドプロンプトのプロパティでコードページを日本語に変えれ
>>446 address space randomizationというセキュリティ対策があって、アドレ
スが一定にはならないようになっているOSもある。
Debianがそうなのかどうかは知らんけど。
>>446 環境によって異なります。仮想アドレス空間だからと言って、同じになる保障があるわけではありません。
>>446 WinXPでは同じになった
Fedoraでやったら起動するたびに違う値になった
基本的にポインタの中身を気にしてはいけない 気にしたところで効率のいいコードが書けるわけじゃないし間違いを起こす可能性のほうが高い
OSやCPUのお勉強のためだろ
2のn乗(nは入力した数)を計算するプログラムを作りたいのですが、 このプログラムではうまくいきません どこが間違ってるのでしょうか。 #include <stdio.h> int main(void) { int n,i; double x=1; scanf("%d",&n); if(n>=0){ for(i=0;i>n;i++){ x=x*2;} printf("答えは%lf\n",x);} else if (n<0){ for(i=0;i<n;i--){x=x/2;} printf("答えは%lf\n",x);} return 1;
>>453 >for(i=0;i>n;i++)
ここと
>printf("答えは%lf\n",x)
ここと
>for(i=0;i<n;i--)
ここと
>printf("答えは%lf\n",x)
ここ
>>453 > 2のn乗(nは入力した数)を計算するプログラムを作りたいのですが、
> このプログラムではうまくいきません
> どこが間違ってるのでしょうか。
> #include
- for(i=0;i>n;i++){
+ for(i=0;i<n;i++){
- for(i=0;i<n;i--){
+ for(i=0;i>n;i--){
x=x/2;} printf("答えは%lf\n",x);}
>>453 × printf("答えは%lf\n",x)
○ printf("答えは%f\n",x)
458 :
453 :2008/07/17(木) 14:37:41
解決しました。ありがとうございました。
構造体の最初の要素のアドレスは常に構造体のアドレスと等しいですか?
構造体が最適化されると違うかもしれない。
>>459 %lfはscanfにはあるがprintfにはない
C99でおk
スタックに値を詰むとき 可変引数が故に常に double へ格上げして詰むことになる だから printf 側からすると 引数は float が来ることはなく %lf は必要ないことになる # が、 %lf をサポートしている処理系もある
>>464 >463
それ以前から、サポートしている処理系が多いことは事実。
>>465 scanf と printf のフォーマット文字列の対称性をもたせるのに
あえて printf での %lf も解釈できるようにしているんだろうね
対称性もたせるというか単に勘違いで書かれたソースを救済するためというか しかしそれで勘違いしたままだとva_arg(ap,float)なんて書いてしまうという更なる罠が
引数の格上げの問題からすれば、 むしろprintfでは%fを廃止して%lfに一本化するのが 正しかった気がしないでもないがいまさら遅すぎだな
そこで、printf()では%gを使うと言う選択ですよ。 冗談さておき、対称性なんて有り得ないんだがなぁ。 初心者本を書いているのが実務経験ない人間だと言うことがよく判るのもこの辺りだからね。
scanfって悪いと言われてますが具体的にどう悪いんですか? バッファオーバーフローを起こす可能性が高いというだけですか?
改行が空白と扱われるのが問題となってますがどう問題なのでしょうか? もし宜しければ検索する為のキーワード等のヒントを頂けませんでしょうか?
n = scanf("%d %d", &a, &b); 1 2<Enter> ならよし 1<Enter>と入力したとき、scanfから抜けてこないということではないかな 1<Enter> 2<Enter> で抜けてくる?(やったことがないのでよくわからん) つまり%dの個数分しっかりと入力する必要があるということ
つまり、fgetsを使用した場合は適当な入力でも とりあえず読み込んで関数を抜けてくれるから 良いと言うことなんでしょうか?
なるほど…下らない質問に答えて頂きありがとうございました
477 :
デフォルトの名無しさん :2008/07/18(金) 01:43:15
>>472 int main()
{
char c;
int d;
scanf("%d",&d);
scanf("%c",&c);
printf("%#x \n",c);
return 0;}
これ実行したらわかるけどscanf("%d",&d);は改行文字を入力ストリームに残すため
次のscanf("%c",&c);では入力ストリームに残った改行文字を自動的に食う
printf("%#x \n",c);を見ればcに0x0a(改行文字)が入ってるのが解る
あー改行文字を残す問題はありましたね、失念してました わざわざ有難うございました scanf("%d", &d); getchar(); と常にしておかないと不味いですよね 併用しなければならない分scanfはやっぱり良くないと… そういえばfgetsを使用した場合指定したサイズより多い数を入力した場合で 入力ストリームをクリアする標準的な方法と言うのを知らないのですが while(getchar() != '\n'); で良いのですかね?
>>478 標準入力をどう利用するかの仕様にも拠るけど、それでいいんでない?
読み捨てちゃ拙いんだったらダメだけど。
良さそうですか?分かりました! 色々とありがとうございました
>>478 いっとくが%dや%sで読むぶんには改行を含む空白を読み飛ばすのでその必要はない
不用意に%cを使うからおかしくなるだけ
あ、はいそれは分かってます ご忠告ありがとうございますw
っと、すみません後一つだけ宜しいでしょうか? 文字列を読み込む場合scanfを使って char buff[256] scanf("%255[^\n]%*[^\n]", buff); getchar(); と書くのもあんまり良くないんでしょうか? こうすれば入力ストリームのクリアも考えなくて済むので 良さそうかなと思ったりもするのですが
いや、それも実験君には使う手だね。 本番ではそういう仕様で済むことがないので使わないけど。
本番ではですか、なるほど やはり実際の現場では使えないのですね… もうちょっと勉強します
>>483 いきなりenterが入力されることを考えて
scanf の前に buff[0]='\0'; が欲しい
それは盲点でしたw うーん…いろいろな事を想定するというのは難しいですね
つーか、scanf()の戻り値は見なきゃダメだろ。
エラーチェックはやりだしたらきりがないな・・
%sで受け取った場合でもエラーが出る状況ってあるのでしょうか? その辺りがまだ経験が足りなくて良く分かってないんです、すみません…
つまりEOFを入力した場合は読み込まれず入力ストリームに 残りっぱなしになるという理解で良いでしょうか?
>>490 自分が期待している処理よりも、期待しない処理のほうがはるかに多いのが常。
期待しない処理を取りこぼしたとき、いわゆるバグが発生する。
>>490 それはバッファオーバーランという別の罠がまっているかもしれません。個人的に %s は使いたくないです。
>>493 とりあえず、C言語を大雑把に全体的に勉強したので
次はもっと細かいところに目を向けようと思ってまた勉強してるのですが
難しいですねやっぱりw
>>494 あ、いえ質問の意図的には
>>483 のような手法で受け取った場合と言うことなんです
変な表現をしてしまってすみません
496 :
デフォルトの名無しさん :2008/07/18(金) 03:52:51
>>483 文字列読み込むなら
#include <stdio.h>
#include <string.h>
int main()
{
char *crlf;
char buff[256] = {'\0'};
fgets(buff,sizeof(buff),stdin);
if(crlf = strrchr(buff,'\n'))
*crlf = '\0';
return 0;
}
みたいな感じ
何故変数名がcrlfなんだか。
俺は特に変だとは思わなかったが 別にwin以外でコンパイルしたとしても 蛇足な名前をあえて使って意味を込める手法は良く取られると思うが。 それとも最初にpがついてない事を言っているのか
敢えて scanf での取り込みで言うなら、改行や空白は取り込まないから isspace辺りで切り落とすとか
まあなんであれfがformatの意味であることを意識しないとトラブルのもとだ あくまで書式が決められた文字列入力解析用の関数だからね
>>498 crlfと言えば、普通は"\r\n"だな。
>>501 ファイルから読み込む訳じゃないから取得データが\r\n→\nとかじゃないんだな
これは失礼いたした
lbとかlnbkとかがいいかもな
double hoge[SIZE]の配列を確保したいんですが、確保に成功したか、失敗したかで場合わけするにはどうするんですか?
>>503 意味がわからん
hoge[SIZE]は静的に確保される位置で定義するの?
それとも動的に確保するの?
SIZEは予めわかってます。
いやそういう意味で聞いてるんでは どうせ #define SIZE 128 とかしてるんでしょ?
そうです。SIZEが大きいので、ちゃんと確保できたか心配なのです
>>507 malloc使って領域確保して・・・
とかじゃなければコンパイルもしくは実行時にわかるよ。
まーたぶんコンパイルは間違ってなければ通るので
実行時にメモリ不足でこけるかどうかだろうね。
でSIZEは何ぼ?
doubleって8バイトしかないよ?
32768です。これが6本ぐらいです
チイサッ
起きやすいのはstack overflowかね。 staticにとるなら実行時の心配はまずしない。 mallocでヒープにとるとしてもその程度なら全然。
まー開発環境が何かはしらないけど 計算してみなよ。 32768x8x6 = 1572864 まー約1.5M? マイコンじゃあ厳しいけどwindowsだと1024x768フルカラーBMPやwavデータより軽いね
>>509 組み込みなら知らないが
動的確保すれば今時のPCなら問題ないレベル
32k*8*6=1.5M
確実に成功したか失敗したかを捕まえたいならmallocして戻り値を見るしかない
大学で明解C言語っていう本使って授業受けたけどぜんぜん理解できなかったorz 俺みたいな馬鹿でも理解できそうな本はありませんか?
本があれば分かるって言うようなもんでもないよ
だな 簡単なプログラムを動かせ
>>515 そういう質問はよくあるが、お前の馬鹿さ加減なんて言葉じゃ伝わらないし、
解説本の類が馬鹿でも分かるから馬鹿には分からないまで順序付けられるわけでもないから、
正直ひとそれぞれだとしか答えられない。
アマゾンの書評でも読んで良さそうだと思ったのを、大きな本屋いって立ち読みすればいいと思うよ。
まあ目的に応じて行き詰ったら調べたりなんだりすればいいと思うよ 基礎的な事ならどの本も似たようなものだし
ありがとうございます 夏休みに色々探してみようと思います
俺の持論だけど 自力で学習できる能があるやつはどんな本使ってもものになるし そうでないやつはどんな本使っても教師がよければいいしダメだとダメ
それは俺も思う
自分がどこにいるかわからない人間にはどんなに詳しい地図があっても意味がないみたいなもんだな。
ていうか勉強なんて本読む、コード読む書く以外にすることなんてあるの?
コードを書くとか
528 :
527 :2008/07/18(金) 22:52:25
あれ?既に書いてあった もう寝よう・・
>>521 ずっと昔から使っているんですけれども、いまだに、なんだかとっても不安なんですが気のせいですかそうですか
一冊だけじゃなくて、複数読む、実践して確かめるなどしないと 本が嘘を書いてある場合があるので要注意。
いのったりねんじたりとかすればC言語使えるようになるよ。
日本の大学の情報の教員で本当にわかってるやつってどんくらいいるかなー
心を無にし、Cに身をゆだねるのだ。そうすればおのずとコードが書けるようになる
>>532 なに、あなたが心配するまでもなく、多くの人間が理解していると思いますよ。
昔は、far とか near とかを駆使してやっていたんです。
なぜいきなり昔の話を
よく分からないがfarとnearを駆使するとすごいらしい
他の人が書いたソースを弄りながら本読んだ方が近道だった
unistd.hって何の略ですか?uniってunixですか?
うん
#include <stdio.h> int main(void) { int a; a=5; printf("%d",a); これでやると a.c: In function `main': a.c:6: error: parse error at end of input となってしまうんですが、どこか間違っているんでしょうか?
「}」 が抜けてただけでした。すいませんでした。
抜けてたのは「間」だろ。
わずか6行のプログラムで・・・
7行?
malloc(3)でいくら確保したか分かる関数ってありますよね? 確保したポインタを渡せば。教えてください。
>>545 残念ながらないのです。自分でラッパ関数を作って覚えておくしかないでしょうね。
floatの絶対値の範囲について質問です。 約-10^38 〜 10^38の実数となっているのですが、 なぜその範囲になるのかがわかりません。 float値 = (-1)^(符号部) * 2^(指数部-127) * 1.仮数部で計算すると -10^-36、10^36となるところまではできたのですが 38乗にするには何が足りないのでしょうか 初歩的な質問で申し訳ありませんが、お願いします。
>>547 最大値
〜2^(2^7 - 1) * 2
〜2^128
〜10^(38.4)
はいかが?
あんまり関係ないけど、Cにべき乗の記号なんて無いことを忘れて ^ を使ってしまう今日このごろ。 へこむわー
Linuxで、ディレクトリストリームから個々のファイルのstat構造体型を 次々と取り出したいのですが、いい方法はありますか? 下の方法で一旦ファイルディスクリプタを取得してからfstatで取り出すと ディレクトリの方のstatを取り出してしまい、上手くいきません。 DIR dir=opendir("."); struct stat dirstat; struct dirent *dirent; while ((dirent=readdir(dir)) != NULL ){ fstat(dirfd(dir), &dirstat); printf("I-node number: %ld\n", (long) dirstat.st_ino); } できればファイル名を用いてstatを取得したくないです。 よろしくお願いします。
これはまたみにくいな
>>553 .
と
..
を除外したいということ?
ディレクトリ全般の情報が必要ないということ?
_findfirst とかは?
556 :
553 :2008/07/20(日) 00:22:00
>>554 ごめんなさい
>>555 いえ、"ls-l" みたいなのを実現したいんです。
上のプログラムではテスト用としてi-nodeを表示させてるのですが、
direntはどんどん先に進むのに、statは前に進まず...
statもファイル名を指定すれば取得できるのですが、フルパスを設定
するのもめんどいし、せっかくディレクトリストリームが取得できて
いるんだから(ディレクトリストリームが何者かはしらんが)それを使って
ファイルを参照した方がオーバーヘッドが減るんじゃないかと思いまして。
>>556 環境依存スレへどうぞ。
まぁ、ディレクトリのステータスを取る関数でファイルのステータスが取れるかについては移動してまでも聞くようなものでもありませんが。
Linuxで用意されてる関数はよく知らんけど 要するにディレクトリ内部のファイルstatを次々に取り出したいわけでしょ じゃあディレクトリストリームを引数にとってstatかファイルディスクリプタを返すような そういう関数がないかどうか調べるんだ ないならいちいちファイル名ひっこぬいて変換するしかない
#include <stdio.h> int main(void) { char a; scanf("%c",&a); printf("%c",a); } とやると a と打ったら a と表示されるのはあたりまえですが、 こんな感じで a と打ったら アスキーコードの 97 と表示されるようにしたいのですが どうしたらいいでしょうか?
%d
#include <stdio.h> int main(void) { int a; scanf("%d",&a); printf("%d",a); } こういうことでしょうか? これだと $ ./a.exe a 4199268 こうなってしまうのですが・・・
なぜscanfまで%dにする
#include <stdio.h> int main(void) { char a; scanf("%c",&a); printf("%d",a); } あ、これでできました。 ありがとうございました
564 :
553 :2008/07/20(日) 01:45:56
どうも、お世話になっとりますです。 C言語初心者ですが、頑張ってgnu_lsのソース読んでみました。 そしたら、ガリガリファイル名使ってstat呼び出してました。 なんで、ないかもしれないです。なんで、フルパスとファイル名を 頑張って取得して作ってみます。ありがとうございました。
なんでchar型で質問して後でintに直して文句を言う
え〜っと、charとintの違いすらよくわからないもので・・・
>>553 オープンしたディレクトリにchdir(2)しとくといいよ。
質問なのですが マージソートなどの領域計算量とはどのように求めればいいのでしょうか お願いします
マージソートを理解していればどれくらい領域が必要か分かるはずだ
時間計算量がO(n log n)になることまでならなんとか
あのぉ…Windowsの改行ってのはCR + LFと聞いたのですが、これはテレタイプの 印字ヘッドに起因しているらしいですが、ちょっとよくイメージできないので誰か教えてください。
CR → 復帰 → 左端に移動 LF → 改行 → 下に移動
>>572 印字ヘッドを右から左に動かすのに200msecかかるらしいのでその間の文字が
消失するようなことを聞いたのですが、テレタイプ自体知らないのでどういう風な構造で
動いているかまったくイメージ出来ないのです。ごめんなさい。
(電動)タイプライターの遠隔操縦版だよ。 まさか、タイプライターを見たことがないってことはないよね。
そうか、いまやプリンターもページプリンタばかりで ラインプリンタとか見ないしなー
ネットのプロトコル関係もCRLFだな。
>>573 読み上げてもらった文章を紙と鉛筆で書きとめることを想像してみるんだ。
改行するときも休まず読み上げられたら追いつかないね。そういうときは読み上げる速度を落としてもらうか待ってもらうかするってことかな
>>574 但し、バッファリングがないので「復帰」中のデータは取りこぼします。
ってところかな。
for(i=0;i<10;i++)ループ中に iが奇数番号のときにprintf("奇数\n");としたいんだけど どうすれば?
if(i&2)
普通forよりも先にif文を学ぶもんじゃないのか?
if(i%2) printf("奇数\n");
%使わないなら>580を使って if(!(i&1))だな
初心者が初心者の質問に回答するスレはここですか
入門スレだからな
こんなに優しい気持ちになったのは久しぶりです
0が真なのか偽なのかなんてわかんねw if ( ( i & 1 ) == 1 ) { printf("奇数\n"); } としておけば間違いない。
0は偽 0以外は真
プログラム実行してメモリがどれくらい消費したかをみるにはどうすればいい?
つ topコマンド
linuxでさー プログラムかいてて 中クリックして変なとこにコピペしたことある?
あるけどCtrl+zで簡単に戻せるからなぁ
Ctrl-_ ?
double型ってfloat型に対してdouble(倍)って意味なんですか?
そうだよ。単精度・倍精度って言葉もあるくらいだし。 現実には、倍でないといけないという決まりはないけどね。
externって何のためにあるんですか? 多重定義でエラーにしてくれないなら意味がないように思いますが。
>>599 externをつけた場合とつけない場合で変数の場合は挙動が変わるのだから意味があるのさ。
関数の場合? しらねw
意味合いとしてはshareみたいなもんだよな 分割コンパイルの時しかツカワネ
>>600 変数の挙動の違いについて教えてください。
忘れましたが、グローバル変数の話です。
GCC 4.1.2では同じ名前のグローバル変数を定義しても
リンク時にエラーにならないのですが。
環境依存だし、入門篇で語る内容じゃないからgccスレへどうぞ。
>>602 externをつけて宣言した識別子は、外部識別子であって、実体を伴わない。
つまりその実体は必ずどこか別のソースファイルで
外部識別子として定義されているはずだということを意味する。
externをつけずに宣言した外部識別子は、他に同じ外部識別子がなければ
実体定義として扱われる。externのない複数の同じ識別子の宣言は
そのうち一つだけが実体として扱われる。
>>602 それがエラーにならないのはgccやUinx系の古いコンパイラだけ。
gccだと--fno-commonでエラーにできるはず。
606 :
デフォルトの名無しさん :2008/07/21(月) 14:25:59
質問です 複数の文字列を配列として扱うためには 配列名を定義するときにポインタを付けなきゃいけないのですか? もしそうならその理由も教えてくらさい
日本語かC言語でおk
>>606 そういうことはないと思いますが、なにを想定しているのかCで書いていただくと、意図がこちらにも伝わりやすいかと。
char *p = "hoge"; char *q = "fuga"; char *str[] = {p, q}; こういうことだと思うが。 まあ文字列を格納している配列のアドレスを格納するための配列だからポインタが付くんだろ
610 :
606 :2008/07/21(月) 14:44:58
その場合に上の2行を省いて char *str[] = {”hoge”, "fuga"}; としても同じことなのですか? もしそうならなぜ同じになるのかも教えてくらさい
char *p; p = "hoge"; char *str[1]; str[0] = "fuga"; わかりやすく書くとこういう感じ。
>>610 char *p = "string";
って書けばメモリ空間上のどこかに 's','t','r','i','n','g','\0' がこの順で格納される領域が(実はコンパイル時に)生成され、
しかもこの領域の先頭アドレスが p に格納されるわけです。
char *p[]={"abc", "xyz"}
も同じこと。
"abc" とかけば、その「値」は、どこぞに格納されている"abc"の先頭アドレスになる、ということでしょうか。
こんなトリッキーな書き方があります。
printf("%c\n","abcdefg"[3]);
printf("%p\n", "abcdefg");
実際にためしてくだされば理解がはやいと。
615 :
606 :2008/07/21(月) 14:59:43
じゃあ自分の言葉で説明してみて
あー、うー、
大平さんか
>>618 リアルでお聞きになったのですか?お年がわかるような気が‥‥‥
606じゃないけど便乗させてください。 @char c[][5] = {"hoge", "piyo"}; Achar *c[] = {"hoge", "piyo"}; Bchar **c = {"hoge", "piyo"}; これらはどこが違うんですか?Bはエラーになりますよね ──────────────────────────────────────── char **pp; pp = c; こういう風にできないのはなぜでしょう?@はエラーになりますよね ──────────────────────────────────────── char *c[] = {"hoge", "piyo"}; char **pp; pp = c; @printf("%s", &pp); Aprintf("%s", pp[0]); ──────────────────────────────────────── このAが正しいのは直感的に分かるのですが、@がおかしなことになるのは何故でしょう? &ppは「ポインタのポインタ」の所持する値(アドレス)のポインタ(アドレス)を指し、 そのアドレスは"hoge"の先頭だと思っていたのですが。 どうも理解していたつもりが、全然理解できていなかったようです。
>>620 上
@は、要素が 5 の char の配列の配列を宣言して、それを {"hoge", "piyo"} で初期化している。
ここでコンパイラは自動的に、省略した最初の添字を初期化要素の数から 2 と決定し、
c は c[0][0] から c[1][4] までの 10 の要素を持つ二次元配列となる。
このとき c の各要素には、
[h][o][g][e][\0]
[p][i][y][o][\0]
という値が格納される。
Aは、char へのポインタの配列を宣言して、それを {"hoge", "piyo"} で初期化している。
やはりコンパイラは自動的に、配列の要素数を 2 と決定し、c[0] と c[1] は、
コンパイラによってどこかに用意された "hoge" "piyo" という文字列をそれぞれ指すように初期化される。
Bで宣言しようとしているものは char へのポインタへのポインタである。このとき c はただ一つの char ** 要素しか持たない。
よって、"hoge" "piyo" という二つの文字列(この場合は char * 型の値として扱われる)要素で初期化することは、
型の点でも数の点でもできない。
>>620 下
pp[0] は pp の指しているオブジェクト(正確には pp の指している場所から数えて 0 番目の場所にあるオブジェクト)を返す。
pp が 指しているのは c の先頭要素であり、これは char * である。だから %s で出力できる。
&pp は、pp の指しているオブジェクトでもその更に先にあるオブジェクトでもなく、常に pp へのポインタを返す。
そしてそれは char *** である。%s で出力できるわけがない。
書き忘れ。
>>620 中
上で書いたように、@で宣言した c は配列( char [5] )の配列( char [2][5] )である。
この c は(いくつかの例外はあるが)大抵の場合その先頭要素へのポインタとして扱われる。
つまり、ここで c は配列へのポインタになる。pp はポインタへのポインタである。だから pp に c は代入できない。
>>621-622 丁寧にありがとうございます。よく分かりました。
なんとなくポインタとアドレス、宣言と初期化がごっちゃになっていた気がします。
配列とポインタは似たようなもの、と覚えたものの、細かいところまで理解していないと良くないですね。
一番下についてはただの勘違いでした。
&ppじゃなくて*ppですね……。
>配列とポインタは似たようなもの ポインタが配列の要素を指すことがあることと、 配列が先頭の要素へのポインタとなることがあるだけで、 それぞれはまったく違うものだということを理解しよう
[]演算子がポインタに作用する演算子だということと 配列がすぐポインタになってしまうことを理解できれば全てわかる 逆に言うと大抵の入門書ではここをちゃんと教えない
こんにちわw茅原実里ですw ところでprintf(3)とscanf(3)のフォーマット指定子についてですが、 printf(3)で浮動小数点数を表示する場合doubleでもfloatでも「%f」を 使用しますが、scanf(3)の場合はなぜ「%lf」と「%f」がそれぞれあるのですか?
>こんにちわw茅原実里ですw なにこの痛い宣言
ところでと言っている時点で、その部分は重要じゃないんだろ
>626 printfが受け取るのは値で、これはいつもdoubleに格上げされる 一方scanfが受け取るのは値を納める変数へのポインタで、 その先にある領域の大きさは当然floatとdoubleでは違う
630 :
627 :2008/07/22(火) 17:02:01
痛い宣言の茅原実里へ そりゃ精度の問題じゃないの? なんでそうやって分かれるかの歴史的いきさつは知らんけど。
どの板行っても声優ネタが通じるってすごいよね
>>625 カーニハンという人による入門書にはちゃんと書いてたぞ。
>>630 float型で引数を渡そうとするとdouble型に格上げされるという規則がある。
なんでそうなったのかの歴史的いきさつは知らんけど。
>>633 intへの格上げの方は、当時のハードウェア、現在のハードウェアのいずれにおいても妥当かなと思えるが、doubleへの格上げは
登竜門だが入門では無いな
637 :
デフォルトの名無しさん :2008/07/22(火) 23:11:15
void func(DATA data){ if(条件){ func2(data): } 処理 } void func2(DATA data) 処理 func(data); } DATAは構造体です。 mainでfuncを呼んで、条件にひっかかったら、func2を呼んで処理したあと、funcを呼びなおしています。 これだとfunc処理が2回行われてしまうんですが・・・ 改善するにはどうしたらいいですか?
ソースがどうなってるのか分からないので何とも言い難いが、 void func(DATA data) { if(条件){ func2(data): } 処理 } void func2(DATA data) { 処理 } これじゃいけない理由っていうのは「処理」の部分に隠れているのかな?
>>638 そうしようと思ったんですが、
funcで渡したdataをfunc2で処理しても、func内だと処理される前と変わらないんですよね・・・
どんな処理したいのかが分からない ただ、DATA型の変数dataがfuncで処理するのが不味い形で func2で修正するというのならば void func(DATA data) { while(条件)| /* 条件を満たすまで修正する */ func2(&data): } 処理 } void func2(DATA *data) { 処理 } にするとか? まあどんなソースかさっぱり分からんからなんとも言えない
ちょっと人に説明しずらい難解な感じなんで、自分でやってみることにします。 すいません
やっぱり 1つ聞かせてください。 この構造体の中身を渡すのに function(data); int function(DATA *data){ } みたいになってます。これはどういう事なんですか?アドレス function(&data)みたいに渡してdataの内容を書き換えて戻ってくる みたいに書けません。 他人の書いたスパゲティコードなのでかなりくるしんでます;
どういうことなんですかと言われましても 呼び出し元でdataがどう宣言されてるのか分からないし もしかして配列として宣言されてるなら、そう言う書き方も出来るし
ソースを晒さねばこれ以上は無理だろうな。
何が分からないのか分からんのだが。 上のdataはポインタじゃないのか?
そもそも何がやりたいのかわからんからなんとも とりあえず大元のfuncとfunc2はヘタすると無限再帰して落ちるだろうことはわかった
typedef struct{ signed short l; signed short r; }P1; typedef struct{ unsigned short count; unsigned long datanum; unsigned short bit; P1 *pattern1; }DATA; こんな感じなんですが
誰がDATAの定義を見たいと言った 処理の全体像が見えないと答えようがないと言ってるんだ
とりあえずC言語の入門書か何かを読んだほうがいいんじゃないか 問題を見せずに答え教えてくれといってるようなもんだぞ
DATA *data; とか DATA data[1] とかになってるんじゃないのか?
|unsigned short count; |unsigned long datanum; |unsigned short bit; ここで既にお察しくださいだな・・・
もういいです。これ廃棄します
とりあえず人のコードをスパゲティだとか言えるレベルではないことは自覚してくれ
言おうと思ったことが653に書かれてた
ですね。反省します。ポインタ周りとか学ぶにはどうしたらいいでしょうか?今まで定石的に使ってきたので 全くといっていいほど理解していません。適当なサイトとか教えてもらえたらうれしいです
ここに居る人間はエスパーでもないしスーパーハッカーでもないので お前さんの持ってるソースの目的など誰もわからない 一方でそれが業務ソースだとしたらそれをそのまま出した場合に もし万が一何らかの問題が起きたらお前の責任問題になる 要するにこの問題をこのスレで解決するには お前があくまでもアマチュアであるか、 あるいは自分の言葉で問題を的確に説明できる必要がある
>655 黙ってK&RとCFAQを読む
なるほど、WAVファイルかそれに類似したものをいじってるのね。
参照渡しした構造体のデータを書き換えるにはどうするんですか?
まさかと思うがアロー演算子を知らないとかそんなオチじゃないよね
-------------->
>>660 data->hoge
ですよね?それは知ってます
(*data).count = 0; みたいな感じ。 タイプ数を減らしたければ -> を使えばいいけど、きみにままだ早すぎる。
知ってのに出来ないと言うのはどういう事だろう 誰かそれを俺に教えてくれ
人にはいえない過去があるんだよ
>>664 関数内で書き換えるコードはかけるんですが、
参照渡ししてるのに元の関数で値を表示すると書き換わっていないのです
それは関数内で書き換えるコードが書けてないんだよ
dataの中身を書き換えられないのはどこかにconstがくっついているからとか。
>>668 constがついている程度なら警告は出るだろうが、書き換えはできるよ。
エラーログ貼れば終わりじゃね
constについては、実体がconstなら、 書き換えは鼻から悪魔的な行為じゃなかったけか
構造体の宣言をグローバル化しました。これで一応解決しました。 どうもすいません。構造体の宣伝が Data *dataとなっているんですが、 これはポインタの宣言ですよね?
じゃなかったら困る
dataの中身が書き換わっていないというよりも、 毎回同じ中身で初期化/生成していた可能性があるな。
わざわざポインタ宣言する意味はなんなんでしょうか?
他人のソースをいじる前にやるべきことが山ほどあると思うんだが。
乗算?
動的にメモリを確保したいからとか色々
>>676 int a;
この宣言の意味を正確に答えられたら教えてやるよw
>>680 int型の変数名aという場所を確保ですか?
他人のソースを弄ってみて 1.自分の技量が足りないんだと諦める 2.他人の書き方が悪いんだと諦める 3.自分の技量が足りないので該当ソースに追いつくようひとまず置いて勉強する 4.他人の書き方が悪いんだろうというので解決策を探る 俺は1
>>676 構造体をそこらじゅうにコピーすると、メモリと処理時間がもったいないからです。
だからアドレスだけ受け渡しする。
、、、という側面もあります。
Cはポインタをいろいろな用途に使うからね。
686 :
デフォルトの名無しさん :2008/07/23(水) 07:07:48
お手軽偽装アプリを考えた。 偽装したいファイル(バイナリ?)の0と1を反転させるだけのアプリを作りたいんですけど 何行くらいで書けそうですか?
687 :
デフォルトの名無しさん :2008/07/23(水) 07:07:57
コマンドプロンプト上で文字を赤く表示したい時ってどうすればいいですか?
>>688 cmd.exeでは不可能
command.comなら可能
>>689 command.com上で動かすことを前提にお話しますが
printf("\x1b[31mこんにちは\x1b[m\n");
で表示できますか?
試してダメだったらansi.sysを組み込んでみて。
わかりました。ありがとうございます。
>>686 要望の物なら14行で書けた
別の言語で更にパス認証あり
ファイルの自動認証ありのプログラム組んだがソース無くした事に気づいた…
5行くらいあれば十分だろ。
一行に一つのセミコロンを使って全部で11行 俺はこれが限度だな
1行で書けた
いやつまんないから
いやとまんないから
#include <stdio.h> int main(c,v)char**v;{if(*++v&&!freopen(*v,"rb",stdin))return-1;if(*++v&&!freo\ pen(*v,"wb",stdout))return-1;while((c=getchar())-EOF)putchar(~c);return 0;} 3行にしかならんお…
687「計画どおり」
fcloseせんでいいのか
>>701 プログラム終了時にcloseされるよ。
stderrはstdoutをこういう用途で使った時に出力できる為にもあんのかな
704 :
デフォルトの名無しさん :2008/07/23(水) 13:24:44
質問があります。よろしくお願いします。 fscanf(fdataB,"%f,%f,%f,%f,%f",&b1,&b2,&b3,&b4,&b5); として、5列のcsvファイルを取り込みました。 b1,b2,b3,b4,b5 の順に出力したいのですが、 b2,b3,b4,b5,b1 という風にずれてしまいます。 原因がわかりません。 よろしくお願いします。
706 :
704 :2008/07/23(水) 13:27:16
28,29,117,32,327 -18,28,117,32,327 27,30,117,34,327 -20,28,116,32,327 27,28,115,32,327 -18,28,115,30,327 27,29,116,31,327 -17,28,116,30,327 27,30,116,30,327 -17,27,117,31,327 28,28,117,30,327 -17,27,117,32,327 お願いします
>>706 下記のコードだと問題ない
問題が再現するコードうp
#include<stdio.h>
int main(void){
float b1, b2, b3, b4, b5;
FILE *fp;
char *filename="a.csv";
fp=fopen(filename, "r");
if(!fp) return 1;
while(fscanf(fp,"%f,%f,%f,%f,%f",&b1,&b2,&b3,&b4,&b5)==5){
printf("%f,%f,%f,%f,%f\n",b1,b2,b3,b4,b5);
}
fclose(fp);
return 0;
}
708 :
704 :2008/07/23(水) 14:13:51
#include <stdio.h> #include <iostream.h> #include <math.h> void main() { float bEcg[1024],bx[1024],by[1024],bz[1024],bTa[1024]; float b1,b2,b3,b4,b5; FILE *fdataB; if ((fdataB = fopen("test.csv", "r")) == NULL) { printf("file open error!!\n"); exit(EXIT_FAILURE);} for (i=0;i<LINE_MAX;i++){ fscanf(fdataB,"%f,%f,%f,%f,%f",&b1,&b2,&b3,&b4,&b5); bEcg[i]=b1; bx[i]=b2; by[i]=b3; bz[i]=b4; bTa[i]=b5; } fclose(fdataB); for (i=0;i<20;i++){cout << bx[i] << '\t' << by[i] << '\t' << bz[i] << '\n';} }
/ ̄\ | | < それはC++です \_/ _| |_ | |
710 :
704 :2008/07/23(水) 14:16:25
708、704です その後データを利用するので、配列に格納後に出力しています。
なんか知らんけどfscanfの戻り値ぐらい見ろよ
>>708 値を表示する部分の順番がおかしいんじゃね?
てか、bx, by, bzの三つしか無いけど。
713 :
704 :2008/07/23(水) 14:29:29
bx, by, bzのみを表示したいんですが、
実際は、by,bz,bEcgが表示されてしまいます。
csvに出力した場合も、一行ずれてしまいます。
>>709 さん
すいませんc++です
読んだ直後に表示して何行目でずれてるのか見てみたら
715 :
704 :2008/07/23(水) 14:43:14
>>714 一行一列目のみ飛ばされてそこからずれています。
そのせいで全部が一行ずれてしまっています。
昨日はうまくいってたのですが、今日プログラムを動かしてみたらズレルようになっていました。
以前にもこのようなことがあったのですが、全く弄っていないので原因がわかりません。
デバッガでステップ実行しろよ
ソースと実行ファイルが合ってないんじゃないの
ええと、1行目の1件目のデータを取りこぼしてるわけね? 頭になんかゴミでもあるんじゃないの?BOMとか
複数の言語覚えて当然みたいな風潮があるけど ほかの言語をどうやってCに取り込んで使うの?
なんでCの取り込んで使うの?
他の言語で作ったライブラリをCのプログラムから使う
とりあえず1列目と2列目の間になにかありそうなのはわかるが、 b2に3列目、b3に4列目が入ったあとb4に1列目が入るってのは妙だな… 本当にファイル正しいか?2バイトコード入ってたりしないか?
725 :
704 :2008/07/23(水) 16:07:31
BOM削除しましたが駄目でた;; ありがとうございました。 別の方法を考えてみます。 またお世話になることがあると思いますが、 そのときはよろしくお願いします。
int n = 2; void *p = &n; printf("%d\n", *(int*)p); printf("%d\n", (int*)*p); の違いがよく分かりません。 教えてください。
(int*)*p はエラー voidポインタは逆参照できない
>726 全部pから順に右へ結合する 上はvoid *をint *にキャストしてからその実体を参照している 下はvoid *の指している実体参照してからそれをint *にキャストしようとしている しかしvoid *はその先に何もない(位置だけを記憶している)という意味なのでそもそも参照できないし もしもし仮にint型の実体を参照できたとしてもそれをint *にキャストするのは間違っている
>>726 Cの演算子は識別子(この場合p)から順番に隣へ(右か左かは場合によるがこの場合は左にしかないので左へ)結合していく
だから*(int*)pはまず(int*)pが評価されてそのあと*が結合する
(int*)pはpの持っているvoidへのポインタの値をintへのポインタの値に変換しますよという意味
すると次に、そのintへのポインタの値に*が結合して、これはintへのポインタの値が指し示しているint変数を参照しますよという意味
だからこの場合*(int*)pはnと書いたのと同じになる
同様に(int*)*pと書いたらまず*pが評価されてそのあと(int*)が結合する
*pは、pの値が指し示している「もの」を参照しますよという意味だが、
ここでpはvoid*なのでその「もの」がない、のでエラーになる
読み込むファイル hoge.txt 40 212 252 889 FILE *fp; if(fopen_s(&fp, filename, "r")){ printf("%s が見つかりません\n",filename); return; } for(i=0;i<4;i++){ fscanf(fp,"%d",data[i]); } data[0]=40 data[1]=212 みたいに読み込ませたいんですが、うまくいかないんです。どうしてですか?
うまくいかないとはプログラムが動作しないのか否か それくらいは書こうぜ ソース見れば分かる人は分かるかもしれんが労力は減らしたほうがいいだろう
>>730 おそらく fscanf で & が抜けてる
>>732 うっかりみすでした。&をつけたらうまくいきました。
これで問題はありませんか?EOFの処理とか考えなくてOKっすか?
>>733 問題があるかどうかそれを判断できるだけの情報を持っているのはあなただけですw
質問失礼します。 文字の間に改行が入った文字列を改行なしの文字列にしたいのですが、 例:abcd\nあいうえ→abcdあいうえ どうやったら出来るでしょうか? よろしくお願いします。
一文字ずつチェックしていって '\n' だったら抜く
一文字ずつってのが嫌だったら strtokで\nを元に区切る
>>736-737 ありがとうございます。
strtokは試してみたのですが、その後一つの文字列に戻す方法がわからないのですorz
test
void delNewline(const char* str, char* res) { char ch; while ((ch = *str++) != '\0') { if (ch != '\n') *res++ = ch; } *res = '\0'; }
>>740 char *data[2];
data[0] = strtok(buf,"\n");
data[1] = strtok(NULL, "\n");
delNewline(data[0], data[1]);
printf("%s",data[0]);
このようにやってみましたがうまくいきません、、。
どこが間違っているのでしょうか?何度も質問すみません;
char *data; data = (char *)malloc(ほにゃほにゃ);
>>741 char *s = "aaaa\nzzz\nppp"; // 処理対象の文字列
char res[100]; // 処理結果を入れる領域(処理対象の文字列以上の長さが必要)
delNewline(s, res); // これで res に改行が削除された文字列が入る。
printf("%s\n", res); // aaazzzppp と出力される。
>>740 は動作確認もしてないからバグってるかもしれんけど
>>742 のヒントをもらってもどのようにすればいいかがわかりません。
しかし、これ以上ご迷惑をかけられないので後は自分で頑張ることにしますorz
ありがとうございました。
>>741 dataは「ポインタの配列」で配列の中でポインタ先のアドレスが必要
配列の中のポインタは有効なアドレスを持っていないので
>742のようにメモリを確保しなければならない
下記は別の方法だが、dataをポインタとして宣言してメモリを確保
strtokを使って随時ゲットしていく
int sizebuf = sizeof(char)*(sizeof(buf)+1);
char *data = memcpy(malloc(sizebuf), "\0", sizebuf);
char *slice = strtok(buf, "\n");
do{
strcat(data, slice);
} while(slice = strtok(NULL, "\n"));
#include <stdio.h> void main() { char *str = "地震キタ Y⌒Y⌒Y⌒Y⌒Y⌒Y⌒(。A。)!!!" while(1) { printf("%s\n", str); } }
747 :
デフォルトの名無しさん :2008/07/24(木) 08:10:35
スタティックリンクライプラリの関数の引数と戻り値をヘッダ無しで調べる方法は無いですか?
リファレンスマニュアルを読む
void strcpy(char *s, char *t) { while(*s++ = *t++) ; } このプログラムってナル文字がコピーされて式が評価されたときに偽になるのですか? ナル文字の値は0ですからね。 ということはそれぞれのポインタはこのループが終わった後ナル文字の次を指しているということですか?
>>749 そうだね
俺は代入式の評価のときは( )を余分につけるのが趣味
while((*s++ = *t++))
>>750 そうした方がいいかもしれませんね。
GCCで-Wallスイッチを付けてコンパイルしたら警告が出ましたし。
多分プログラマの意図と違うんじゃないかってことを知らせているのですね。
while(*s++ == *t++) の間違いじゃないですかといいたいんだと思う 間違いじゃないなら( )つけろよ って感じ
代入によって等しくなる両辺揃って評価する、ってイメージで余分に括弧つけてたけど 環境によっては警告出るのね。完全に趣味の問題だと思ってた
よくscanf()なんかでscanf("%d", &n);で数字以外の部分はストリームに 残されるって聞きますけど、ストリームって緩衝領域みたいなのがあるんですか?
>>754 いや、それが昔からのlintで警告を消す方法なんだよ
>>756 病院の待合室みたいな感じじゃね?
scanfでループさせると終わらなくなるのは
「数字さーん、数字さーん、お入りくださーい…あれ?」
「まだ待合室には人がいるわね」
「数字さーん、数字さーん、お入りくださーい…あれ?」
以下略
ってのが繰り替えされるからじゃないかとナース好きの俺の妄想
>>758 いや、それだと順番無視して数字さんが入ってしまうからダメ。
寧ろ、こっちのイメージ。
「はい、次の人どうぞ。
……ダメダメ、あんた数字じゃないだろ。次は数字の番なんだ」
以下同様に
緩衝領域==バッファ
おまいが何に食いついてるのかが分からない
おまいが何に食いついてるのかが分からない
>>752 間違いじゃないかと推測したことが間違いだったから涙目wwww
取り合えずバカな俺にも真偽が分かるように解説頼む
>766 おまえは どうしようも ないな
>752は>751へのレスでコンパイラの警告の意図だろ 何もおかしくない
約一名発狂した方が居られますので お手を触れないようお願い致します
>>752 > while(*s++ == *t++)
==
>>768 は高等な釣り
真偽=booleanは一連の流れの発端>749と掛けている
文章の出だしの「取り合えず」をローマ字表記すると
toriaezu
濁点を清音にするとtoriaesu
並び替えると i sao true
saoを英語的に読むとソゥ、ずばりsawである。
I saw true、私は真実が分かった、という文章になるのだ。
つまり「私の文章が分かったでしょう、本当は解説は不要です」という事だ
\何だってー/
Ω Ω Ω
り、りろんは知ってる
>>752 = と == の違いが分かっていてそれはないわw
つまり、事の発端は>752が代入演算子ではなく比較演算子を書いてしまったところにあるわけだな。
コンパイラが通常 == が入るところに = があって、 == じゃないんですか?という指摘をした という話だろ、何の問題も無い。
読み返したが>752の何が問題なのかが分からなかった
lint が出す警告の意図は ”== じゃなくて = で良いの?” この警告を殺すには 代入式自体を () で囲む
つーか、>752の説明が下手なんだな。 「whileの条件が代入文だが比較じゃないのか?」というのがコンパイラの警告なわけで、 それだけ見れば>752は間違っちゃいないんだ。 つまり、「間違いじゃないなら()つけろよ」ではなく 「代入で間違いないなら()で括っとけ」と書いていれば下らない煽りはなかっただろうと。
代入と比較演算を間違えるバグが後を立たなくて NULL == p とかいう記述をする奴もいるぐらいだしな
日本語力の減退した人間が多いからナァ あ、約一名は別に多くはないか
>>752 が何を勘違いしたか?代入と比較を勘違いした点は直接的ではなく
ポインタの位置についてが質問者の一番の焦点だったわけで。
なのに、比較して一致しなかったらループを抜けるつもりなのか?っと
思い違いをして、括弧がどうとか言い出したから、あれ?ってなったんだが・・・
>>783 それは国民の生活が楽になるように車一台国が用意するべき
ぐらい飛躍した話だな
>752はそこまで酷い記述でも無いし
引っかかったなら引っかかったで後で笑い話にでもすればいい
>>786 その話はとっくに終わっている
勘違いしてるのは お ま え
>>759 なるほど、scanfの失敗の例え、ここに極まり
あとは色んな所にコピペするだけだ
これは凄まじいフルボッコwww
gccはデフォルトでは代入警告出ないのね そーゆー使い方してる人だとピンと来ないんだろうなぁ
795 :
デフォルトの名無しさん :2008/07/24(木) 18:34:31
>>752 の内容をちゃんと読めてない約一名?ex.
>>795 (なの?もっといたりしない?)が、
恥ずかしくて荒らさずにいられなくなってしまったスレが、この辺にあると聞きました。
ここであってますか?
むしろ
>>786 の内容が理解できないのは俺だけですかそうですかorz
俺も分からん
単語二つ三つを繋いでみると別に普通なのに
一文にしたとたん意味が分からなくなる
>>786 の文才は凄いと思うよ
鬼才ってこういうのを言うんだと思う
意味はさっぱり分からないが、何か難しい内容のものを読んだという充実感を読み手に与える奇才だな リアル鬼ごっこの著者とか、そういうタイプ
801 :
デフォルトの名無しさん :2008/07/24(木) 19:07:16
夏ですね
805 :
796 :2008/07/24(木) 19:12:58
>>752 ではないんだが。
真偽判定部分に代入文書くと、比較文の間違いじゃないの?って警告出るの知らない?
> 恥ずかしくて荒らさずにいられなくなってしまった ↑あってると思うからなに言っても無駄だよ。ほっときなw
ID無いからシレっとしてればいいのに
人のレスの間違いなんてどうでも良いよ 突っ込むならどこがどうおかしいか具体的に例示してくれ それをせずに安価さすだけなら要らないよ意味が無いから
>>752 752 名前:デフォルトの名無しさん[sage] 投稿日:2008/07/24(木) 10:21:20
while(*s++ == *t++)
の間違いじゃないですかといいたいんだと思う
間違いじゃないなら( )つけろよ
って感じ
>>749 > ナル文字がコピーされて式が評価されたときに
whileの中は代入だと分かる決定的な証拠、発言があるのだが
どうして評価だと思ったのか?まぁ、とりあえず
>>752 が必死だなってことで、今日の所はこれくらいにしてやって、お前らw
もう
>>752 のHPは0よ、これ以上やったら教会に連れて行っても
神父さんは蘇生させてはくれないわっ!
ドラゴンボール集めも大変なんだからw
人は叩かれて強くなるもんさ
>>811 「コンパイラにしてみれば」
while(*s++ == *t++)
の間違いじゃないですかといいたいんだと思う
間違いじゃないなら「真偽値として扱っていることを明示するために」( )つけろよ
って感じ
>>812 >>749-752 のながれをちゃんとよもう。
>>814 Cマガに取り上げられてまで叩かれた私はどうなるのでしょう?
>>812 評価式のところに代入式を書いてしまうミスが多かったから
評価式の間違いじゃないの?って警告を出すようになったんだよ
>>812 今日のところはこれくらいで勘弁してくださいw逆にw
>>752 (・∀・)ニヤニヤ (・×・)んっーーんっーーアッー!
>>817 衆人環視の中「人体切断、イリュージョンで復活」みたいなw
どっちかといえば切断されっぱなしのままか
>>821 業界に入ってくるつもりがあるならそれまでに理解できるようになっててね
それ以前に日本語力が不足しすぎてるだろ
>>752 必死、涙目、可愛そすぐる ><;
>>749 > ナル文字がコピーされて式が評価されたときに
メモリマップドファイルを用いてファイル書き込みをしたいのですが、 現在のファイルサイズを越えて書き込もうとするとバスエラーに なります。writeを使って無意味な文字を書き込んでファイルの 領域を確保すると上手くいくんですが、他に何か方法ってありませんか?
!!! まだ四面楚歌だということに気づいてなかったの? ずいぶん長いカラオケやっちゃってんだなぁ
>>825 > GCCで-Wallスイッチを付けてコンパイルしたら警告が出ましたし。
>>828 え、まさか業界に、いるの?
いやいやまさか
>>752 をバカにするという発想ができる人は業界にいるはずないよなw
いたらなんかの間違いだろwww
>>752 を日本語に翻訳、要約すると
while(*s++ == *t++) のように、比較して一致しなかったら
ループを終了したいのかな?しかし、質問者はそうではなく
*sにナル文字が代入されたときにループを抜けたいのなら、
while( (*s++ = *t++) ) という感じに
もう1つ括弧で括ったらどうかと?
ってかーんじ。
>>833 どこから直したらいいのか分からんぐらいに壊れてるな
とりあえず出直せ。で、同様のコンパイラの警告を何度か受けて理解しな
あれ、誤爆したかも。
836 :
752 :2008/07/24(木) 20:06:23
俺大人気ジャン こんなの初めて
>>752 なんでわざわざ == と比較演算子にしちゃったん?(節子のAA略)
いや、もう最近の
>>752 って必死でしょ?
>>749 > ナル文字がコピーされて
質問者は代入されていることが分かっているのに、何で比較していると
勘違いしちゃったんですかっ!? ><;
日本語を話せ
if (i = true) というコードがあったとするよな。 これはiの値に関係なく真になるんだ。 しかし、これは if (i == true)のtypoである可能性が高いとコンパイラは判断するんだ。 なぜなら、真偽判定を行う部分で代入処理を行うことは少ないし、 それがtypoであった場合にコンパイルエラーにはならず、バグに気づかない可能性もある。 そのため、==なのではないか?という警告を出力するようになっている。
>>822 ことあるごとにくりかえしくりかえし切断されまくって‥‥‥。
前から居る頭のおかしい子がまた暴れてるのか まっとうなプログラマなら一度は見たことのある警告のはずだが
>>826 あるかもしれないし、ないかもしれない
Cは基本的なファイル操作関数を用意していてそれらが正しく動くことは保証するけれど、
その正しい動作が常にこちらの望む結果をもたらしてくれることまでは保証してくれない
(というかそんなことはできるはずがない)
メモリマップドIOなどの特殊なファイル操作に関する技はいつも環境依存である
環境についているマニュアルを読むこと
>>752 >>750 が説明しているのに、間違いじゃないか?なんて憶測で言ったがために
物議を醸してしまった罪は重い。早々に業界から立ち去れいっ
訳:かまってほしいな
>850 お前が消えろ
どちらかというと、やっと言わんとすることを理解できたけど、恥ずかしいから
>>752 には悪者になって欲しい、というふうに読んだ。
>>854 現在のファイルサイズってどういう意味?
>>856 過去のでも、未来のでもない、今の時点のファイルサイズという意味です。
859 :
デフォルトの名無しさん :2008/07/24(木) 21:08:10
C言語あたりで葉鍵ギャルゲーのようなサウンドノベルゲームを作りたいのですが、お勧めの書籍等ありますか? ちなみに、Windowsプログラム(?)の勉強も兼ねたいので どっかの無名教授・研究者・マが作った凄くマイナーな独自ライブラリ(まるで宣伝みたいな)、 とくにWinAPI等を隠蔽したライブラリを使った開発は嫌です。(勉強にならなそうなので) 実務でより役に立ちそうな開発手段がいいです。 出来れば言語はCせめてC++がいいです。
860 :
826 :2008/07/24(木) 21:08:35
>>856 ごめんなさい、説明が悪かったです。
書き込み先のファイルの終端って事です。
例えば、300バイトしかないファイルや中身が空のファイルに
1000バイトの内容をメモリマップドファイルからSYNCして書こうとすると
バスエラーになってしまうんです。
今のところ、writeで無意味な文字列を書き込んで無理やりファイルサイズを
大きくし、そしてメモリマップドファイルから書き込んでそのエラーを回避して
るのですが・・・
>>859 APIが隠蔽されてるのが嫌ならAPIを直接触れば良いじゃない
そうすればここじゃなくてWin32APIスレで質問するべき話になるし
864 :
826 :2008/07/24(木) 21:25:26
865 :
デフォルトの名無しさん :2008/07/24(木) 21:25:45
そりゃお手本があればコピペ駆使して一晩で簡単に作れるだろ 実務で役に立つような〜というのなら、ゲームで縛らず素直にWinAPI学べばいいと思う まあ本格的なゲームになるとDirectXに移行したほうがいいけど、 それでもWinAPIの知識は必要になるし、やっておくにこしたことはない
867 :
デフォルトの名無しさん :2008/07/24(木) 21:28:38
"20080724" となっている日付に、+1したいんですが、どうすればいいんでしょうか? また、日付の比較もしたいですが、散々探して分かりませんでした。 すみませんが、教えてください。
>>826 手元の本(はじめての486, 蒲池輝尚, アスキー1994)では、ファイルポインタの移動は lseek() でやっていますね。とすると、ファイルサイズを超えたアクセスは無理でしょうね。
Linux の実装ではどうなっているのでしょうか?
>>867 文字列中の最後の文字に1を加算すればいいんじゃね?
でも31日とか30日しかない月の場合は月の箇所を、
場合によっては西暦も変更する必要がある
比較って何をどう比較するかも書いて欲しい
>>867 文字列を数字化して加算、比較
必要な時に文字列化
int i;
char str[10];
i atoi("20080724");
sprintf(str, "%d", i);
871 :
デフォルトの名無しさん :2008/07/24(木) 21:40:09
>>869 すみません。それってやっぱりものすごい手間ですか?ガリガリ書かなきゃ
ダメって感じでしょうか?簡単な関数とかはないでしょうか?
比較は、
if("20080724" > "19990101")
という感じで、日付を比較したいんです。
873 :
デフォルトの名無しさん :2008/07/24(木) 21:42:01
DirectXは習得までに10年かかるので 本気でゲーマーにならない限りお勧めしない WindowxsAPIも一人前になるのに5年はかかる
>>873 10年もあったら仕様が全く変わってしまう
DX7 DX9 DX10 ぜんぜん違う
875 :
デフォルトの名無しさん :2008/07/24(木) 21:44:44
>>870 説明不足で申し訳ありません。+1日したいんです。
それだと、7月32日とかになっちゃいますよね・・。
やっぱり自作関数レベルのおおごとでしょうか・・・orz
自作関数の何が大事なんだ?
>>874 あの時代は本当に泣かされたよな
本読んでも全然コンパイル通らないし入門者に鬼門だった
879 :
デフォルトの名無しさん :2008/07/24(木) 21:50:35
だからこそスキルもついた
バッドノウハウもね。
881 :
デフォルトの名無しさん :2008/07/24(木) 22:23:37
>>872 ありがとうございます。strcmpって、同じ文字列かどうか比較する以外にも
使えるんですか?日付の大小が比較できるんでしょうか?どうやるんですか?
>>876 マジで自作関数ですか・・・orz
>>875 標準で用意されていないから自作ですね。
< とか > では比較できないです。
ただ、YYYYMMDD形式なら文字列の大小がそのまま日付の大小と一致するのでstrcmpでよいです
>>881 strcmp(a, b) で、aが大きかったらプラス、bが大きかったらマイナス、等しかったら0が返る。
885 :
デフォルトの名無しさん :2008/07/24(木) 22:35:11
>>882-883 ありがとうございます!!
while(YYYYMMDD > YYYYMMDD)
のようなことをやりたいんですが、こうなりますか?↓
while( strcmp(a, b)> 0 )
>>884 頑張ります・・うう・・
struct tm 使っちゃえYO!
strftime()とかlocaltime()とかを使う
>>881 12345年1月1日のつもりの"1234500101"と
2008年7月24日のつもりの"20080724"を比べるのでもない限りうまくいく。
桁数が同じなら、より後の日付の方が文字コードの辞書式順序でも後に並ぶのは明らか。
そもそも文字列で扱うのをやめるという選択肢はないの?
日付時刻の内部的な扱いにはtime_tのようなシリアル値が一般的。
time_tなら、mktimeを使えば7月32日のようなぶっとんだ日付でもtime_tにしてくれる。
唯一の気がかりは2038年問題だけど。
あるいは素直にC++を使う
>>888 > そもそも文字列で扱うのをやめるという選択肢
それができるレベルになってないだけだと思うので、time.hとかstrftimeとかの
キーワードを元に知識を深めることができるタイプだといいな。
文字列で扱う方がレベル高い話だと思うんだ俺
やってみたよ。面倒だよ。 #include<stdio.h> #include<stdlib.h> #include<time.h> long translate(long value){ struct tm x={0}; time_t y; x.tm_year=((value/10000)%10000)-1900; x.tm_mon=((value/100)%100)-1; x.tm_mday=value%100; y=mktime(&x); x=*localtime(&y); return (x.tm_year+1900)*10000+(x.tm_mon+1)*100+x.tm_mday; } int main(void){ char str[]="20080732"; puts(str); sprintf(str, "%lu", translate(atol(str))); puts(str); return 0; }
宿題のレベルがあがってこっちに逃げたらここでもフルボッコw
提供されている構造体を理解し、それを使うというのはなんとなく 敷居が高いように感じてしまう時期があると思うんだ 自作関数がオオゴトだと思う頃みたいだし
次はsscanfでやろうぜ
>>895 自作関数(って名前ができる事自体違和感だが)って
初めてのコンパイルから分割コンパイルの間ぐらいかなと思う
ってか未だにsetjmpとか使いこなせない…
ダメではない キケンなだけだ
900 :
デフォルトの名無しさん :2008/07/24(木) 23:20:06
>>888 ありがとうございます。実はPro*Cで、日付のシリアル値をとってこれなかった
(とってき方が分からない)ので、文字列にしてみたんです。
CHAR 8byte のYYYYMMDD のカラムAを、
SELECT
TO_DATE(カラムA, 'YYYYMMDD')
INTO
:shoriDate
みたいに変数に入れてみたんですが、どうもダメなようで、C言語で
日付計算なら容易いかな、と思ってたんですが、とんでもなかったです。。
901 :
デフォルトの名無しさん :2008/07/24(木) 23:27:39
>>893 わざわざありがとうございます!!!難解すぎる・・・。
日付を文字列で扱うこと自体、あまりスマートじゃないんですね。
シリアル値でとってくる方法、もう少し頑張ってみようかと思います。
若干スレちすみません。
むしろSQLで日付に1足せばよくね?
903 :
デフォルトの名無しさん :2008/07/24(木) 23:38:55
>>902 いや、SQL外部で処理する必要があるんです・・・。
while()
{
日付 = 日付 + 1
}
と、するんですから。
そのループ回数はSQLで取得できるものに依存してるのかどうかとか 分からないことだらけだけれど、SQLと連携する段になったので 可能な限りCでやらずにすむ方法を考えた方が楽だと思う。 なんならストアドファンクション作るって考えもあるわけで。
これなら簡単に見える? char *date = "20080724"; int i; int year, month, day; char y[5], m[3], d[3], str[9]; for(i = 0; i < 4; i++) { y[i] = date[i]; if(i < 2) { m[i] = date[i + 4]; d[i] = date[i + 6]; } } y[4] = m[2] = d[2] = '\0'; year = atoi(y); month = atoi(m); day = atoi(d); day++; sprintf(str, "%d%d%d", year, month, day);
>>905 sscanf("20080724", "%4d%2d%2d", &year, &month, &day);
この方が楽かと
でも、日付の処理はしないといけない
+1 しかありえないなら閏年判定して月の最終日を求めるだけでもいいけど
907 :
デフォルトの名無しさん :2008/07/24(木) 23:58:04
>>904 小出しで申し訳ありません。
while(日付A > 日付B)
{
/* TBL更新処理 */
(略)
日付B = 日付B + 1
}
てな感じです。日付Bはこの処理の前に、SQLでSELECT INTOして来て使ってます。
ストアド作るほど大げさなプログラムじゃないと思うんです。てか思いたいんです・・。
人それぞれだとは思うが 関数の大きさは画面一杯って言う人もいるぐらいだから 例え単純な処理でも関数に分けちゃっていい場合もある
うーん。 SQLの方が向いている処理、Cの方が向いている処理というのがあるからね。 SQLで解決できないことが分かった上でならいいんだけど、 なんでSQLでやらなかったんだろう?って思われないようにSQL側でも検討 してみたらどうでしょ。 その気があるならテーブルレイアウトとやりたい事を明確にしたうえでSQLスレにどぞ。
911 :
デフォルトの名無しさん :2008/07/25(金) 00:25:15
>>905 なんとか(涙)
でもホントにここまでやらなきゃだめなほど、大変なんですね・・。
>>909-
>>910 ありがとうございます。私もできればSQLの方が得意なので、もうちょっと
考えてみます。(私が考えた設計ではないので)
>日付の処理 sscanf()でyear, month, dayに分離したら、struct tmに放り込んでmktime()でOK。 放り込むときに日数の調整もしてしまえばいいし、なんら難しいことはないと思う。
// >912を作ってみた。 // mktime()が強力なので、おかしな日付も適当に解釈してくれる。 // 例えば、./a.out 20000000 と実行すると2000-01-01の一ヶ月前の一日前(=1999-11-30)として処理されるのが判る。 #include <stdio.h> #include <time.h> int main(int argc, char ** argv) { int year; int month; int day; if (sscanf(argv[1], "%04d%02d%02d", & year, & month, & day) != 3) { fprintf(stderr, "%s is illegal form.\n", argv[1]); return 1; } char buf[20]; struct tm tmp = {0, }; // 1900-01-00 09:00:00で初期化。時刻計算が入るときは要注意。 tmp.tm_year = year - 1900; tmp.tm_mon = month - 1; tmp.tm_mday = day; mktime(& tmp); strftime(buf, sizeof(buf), "%F", & tmp); // %Fが正規に使えるのはC99から。そうでなければ%y/%m/%dとでも printf("Next day of %s ", buf); ++ tmp.tm_mday; mktime(& tmp); strftime(buf, sizeof(buf), "%F", & tmp); printf("is %s.\n", buf); return 0; }
マンドクセッ どうせ内面的には、日付に関する情報は シリアル値といって、ある基準の日付から経過した秒数で 管理されているわけだから、それを指定した書式に展開する ライブラリを用いて管理した方が楽だし。わざわざ年月日を 文字列として扱うとか、マジ面倒臭ぇ〜●ンコの臭いがぷんぷんすんぜ、くらい臭ぇ。
void (*p[])(void) = {foo, bar, baz}; って定義があった場合に p[1](); みたいにして関数を呼べますよね? p[1]()は(*(p + 1))()のシンタックスシュガーですよね? ではなぜp++は出来ないのですか?
配列だから
int i[2]; int *n; n = i; i++; /*できない*/ n++; /*できる*/
p[1] と *(p+1) は実質同じだけれど p+1 と p++ は違うからね
919 :
デフォルトの名無しさん :2008/07/25(金) 18:57:29
一様乱数を生成する関数のソースについて質問があります。y=1/sqrt(2)*exp(-1/2*x*x)の計算で In function `GaussRandom':: undefined reference to 'sqrt’と In function `GaussRandom': : undefined reference to `exp'というエラーがでて実行できません。もちろん<math.h>は定義しました。 レポート課題なのでマジで困ってます。是非教えてください。ソースを下に載せておきます。 ちなみにxが一様乱数で、yが正規乱数です。 double GaussRandom() { double x; double y; x=UniformRandom(); y=1/sqrt(2)*exp(-1/2*x*x); return y; } double UniformRandom() { double x; int r=1; r=1229*r+351750; x=r/1664501; return x; }
マルチし過ぎだろ…
>>919 コンパイルオプションの最後に -lm を付ける
って、なんだマルチか 答えて損した
923 :
デフォルトの名無しさん :2008/07/25(金) 19:15:07
>>922 期限が迫ってたので色んな所で聞こうと思っただけです。
今度からは自重します。すいません。後ありがとうございます。
犯罪者の言い訳に似てる
期限が迫ってたらなにやってもいいのかよ。 つか、そのレベルの悩みはそのコードを書く途中で出てくるものであって コードを書き上げて出てくるもんではないよな。 他人のソースを理解しないまま提出するすべての学生に災いあれ
Cならなんでも聞いていいんだな?よし じゃあファイル操作に関する制御文?(printfとか)を知ってるだけ挙げてほしい 意味は自分でググルから頼んだ
>>926 とりあえず stdio.h と io.h を読め
printfが既にファイル操作関係ない件
fopen fclose fwrite fread fseek ftell fgetc fputc fprintf fscanf vfprintf vfscanf fputs feof ferror あとなんかあったっけ
どうでもいいが、printfは関数であって制御文じゃないぞ。
>>930 fgetpos, fsetpos, rewind, 忘れちゃいけないfgets。
このスレでも出てたが freopenも
CreateFile()
C標準だけでディレクトリのすべてのファイルを調べるにはどうすればいいの?
>936 できない Cにディレクトリという概念は無い
>>936 C言語の仕様にはディレクトリの概念は無かったと思うよ
ただ opendir readdir closedir はほとんどのコンパイラで使えると思う
>>940 逆に>939が冗談ではないと言う仮定からスタートすれば、
>939が狭い了見しか持ち合わせていないことが判ろう。
>>939 LSI-C には無い
LCC には無い
Borland C++ Compiler にはある
gcc にはある
_dos_findfirst _dos_findnext とか findfirst findnext とか なら似通ってるのがあるな
VCにもDMCにもないよ。
騙されそうになった
C言語でプログラム書いててサイズがでかくなってくると分割していくけど xxxx.cとかいう単位ってなんて表現すればいいんだ? C#なんかだとクラスとか呼べるがCの場合そういう表現方法がないような・・・
モジュール?
fftのプログラムつくりたいんだけど どういう手順で作っていけばいいと思いますか? 丸投げするのもなんだし、関連サイトみても仕組みがわからないからかけない
949 :
946 :2008/07/26(土) 03:03:09
>>947 ありがとうございます。
C言語ではモジュールというんですね。
>>949 言わないよ。
うちでは単に「ソース」と呼ぶ。
ってゆーか今日連発で質問してるひとって同じヒト?
>>949 cはソースファイル
hはヘッダファイル
と呼んでいる
const int ARRAY_SIZE = 100; int array[ARRAY_SIZE]; って出来ないんですけど。
954 :
949 :2008/07/26(土) 07:54:10
もうモジュールとか呼ぶのは古いのかな?^^;
>>953 //こっちをヘッダとか定義してる上のほうへ
#define ARRAY_SIZE 100
int array[ARRAY_SIZE];
>>953 Cでは変数を定数値として扱えないので大人しく>954のようにマクロを使うしか。
>>949 普通にソースファイルとインクルードファイルと呼んでいる。
>>954 モジュールと言う概念とソースファイルと言う概念は一対一に対応しない。
寧ろ、出来上がったバイナリファイルの単位で使うケースが多いと思われ。
cf. 実行モジュール、オブジェクトモジュール &c.
つ C99
>>957 そのばやい、sizeof arrayにちうい。
>>946 ちなみに、Cの規格書の中では翻訳単位 (translation unit)という言葉を使っている。
普段はあまり耳にしないけど。
コンパイル単位って言いますよね。
翻訳単位は、インクルードしてるものを全部含むんじゃないか?
含むからこの場合は、適当ではないね。
大手インターン決まった俺は勝ち組 1ヶ月がむばってくる
というか、対比で出てきてるのが「クラス」なんだから、ファイル単位とかあんま関係なくない? 方言だろうけど、うちの場合「機能モジュール」とか呼ばれてるもんぐらいの範囲と思われ。
1クラス1ファイルはJavaなら当たり前のことだからね。
ネストクラス使いまくりです
こんにちわw平野綾ですw ところで文字列リテラルって配列なんですかね? それともcharへのポインタなんですかね?
968 :
946 :2008/07/26(土) 16:25:56
>>959-962 >>964-966 うーん
やはり古い言語だけあっていい表現がないですね〜
これがC++になるとクラスの概念がでてくるので問題ないんでしょうけどね〜
今うちで分けてる方法はまさにクラスのような感じで1ソースファイル内でデータの管理とそれに関連する
処理を行っていて、関連する別ソースからは関数経由(この場合はインターフェース?)でないと
情報の取得や更新ができないようにしてるんですよね・・・
でもクラスのように動的に生成されるわけでもなく、コンパイル時に実行ファイル内に取り込んじゃうので・・・
関数呼び出し foo(); って実はポインタなんですかね? fooだけで見ると それでパーレンが付くとその関数呼び出しということになるのでしょうか?
>>969 まあアドレスわからないと呼び出せないよね
>>969 それを裏付けるかのように、配列がポインタに変換されるのと同じように、
関数は関数へのポインタに変換されるという規則もある。
昔の偉い人も同じような考えに至ったらしい。
>>969 関数ポインタに括弧つけると関数呼び出しになる。
&演算子のオペランドでない関数は関数ポインタに成り下がる。
(**********************************printf)("Hello, world");
((void (*)(void))0x00040000)();
>>968 クラスはモジュール分割のためにあるわけじゃないよ。
クラスと言うキーワードで全てを理解しようとしすぎているように感じる。
梅
竹
松
杉
桜
楓
檜
榎
桃
柿
桐
椿
樫
橘
楠
楡
楮
柳
橡
桂
椎
椚
ぶひひ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。