トップページ⇒tech
909コメント312KB

C言語なら、俺に聞け! <9>

■ このスレッドは過去ログ倉庫に格納されています
0001C言語ハッカー Kusakabe YouichiNGNG
おれは21才、9年間プログラムを一生懸命作ってきた。
あちこちの言語に手を出したが結局極めたのはC言語だけだった。
大体のことなら分かるからオレに聞け。

だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。

・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html

・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html

・前スレ C言語なら、オレに聞け! <8>
http://pc.2ch.net/test/read.cgi/tech/1005811510/l50
0369Kusakabe YouichiNGNG
In article >>368, 368 デフォルトの名無しさん wrote:
> >>367
> それより、>>351 答えたら。

どんな質問?
0370デフォルトの名無しさん NGNG
>>369
なんだ、マ板でニセモノ合唱されたら、こっちに逃げてきたのか。
0371デフォルトの名無しさんNGNG
日下部先生愛してます
0372デフォルトの名無しさんNGNG
くさかべせんせえ、下は九九を表示するプログラムで、両方とも
コンパイラは通るのですが、

#define ROWS 9
#define COLUMNS 9

1)
main()
{
int i;
int j;
int **k = (int **)malloc(sizeof(int) * ROWS);

for(i=0;i<ROWS;i++)
{
for(j=0;j<COLUMNS;j++)
{
k[j] = (int *)malloc(sizeof(int));
}
}

for(i=0;i<ROWS;i++)
{
for(j=0;j<COLUMNS;j++)
{
k[i][j] = (i+1) * (j+1);
printf("[%d x %d = %2d]",(i+1),(j+1),k[i][j]);
}
printf("\n");
}

return 0;
}
は実行されるのですが、

2)
main()
{
int i;
int j;
int **k = (int **)malloc(sizeof(int) * ROWS);
for(i=0;i<ROWS;i++)
{
for(j=0;j<COLUMNS;j++)
{
k[j] = (int *)malloc(sizeof(int));
k[i][j] = (i+1) * (j+1);
printf("[%d x %d = %2d]",(i+1),(j+1),k[i][j]);
}
printf("\n");
}

return 0;
}
は実行時エラーが出て止まります。

なんでですか?
0373デフォルトの名無しさんNGNG
メモリ確保
ってなんでする必要があるの?
0374デフォルトの名無しさんNGNG
会社とかで
「会議室を使いたい」
と思って、予約しないで勝手に使いたい時間にいくと、既に他の部署の人に使われてたりする。

なので、
「何月何日の何時何分から何時何分まで会議室を使います」
と予約しておく必要がある。
0375デフォルトの名無しさんNGNG
>>372
なぜメモリ確保するのかは聞かないことにして、

k[j] = (int *)malloc(sizeof(int));
ではなく
k[j] = (int *)malloc(sizeof(int)*COLUMNS);

すべきでわ?
0376デフォルトの名無しさんNGNG
>>372
2)は↓こうすべきだと思うが

main()
{
int i;
int j;
int **k = (int **)malloc(sizeof(int *) * ROWS);
for(i=0;i<ROWS;i++)
{
k[i] = (int *)malloc(sizeof(int)*COLUMNS);
for(j=0;j<COLUMNS;j++)
{
k[i][j] = (i+1) * (j+1);
printf("[%d x %d = %2d]",(i+1),(j+1),k[i][j]);
}
printf("\n");
}

return 0;
}
0377ikuNGNG
>>274
返事が遅くなってすいません。
みなさんご意見どうもありがとうございました。
fprintf(fp1,"%s,%s,%s,%s\n",strPath,strSheet,strPCNAME,strErrMsg);
で解決しました。
0378ikuNGNG
こんばんは。fprintfについて教えて下さい。
下記の様な処理でファイルからデータを読みこんでbuff1にデータを
文字列で格納しました。
この読込んだデータはc:\\test1\\というパス名なのですが
ファイルからこのデータを読込んでa.txtというテキスト名を
くっつけたいと考えています。(c:\\test1\\a.txt)
この操作をするにはbuff1+"a.txt"なんてすれば良いのかな?
と思いやってみましたがbuff1の値が化けてるいる様です。
どうやったらc:\\test1\\a.txtの値を取得できるか教えて頂きたいのですが。
よろしくお願いします。

if (NULL == (fp0 = fopen(mvemFilename.c_str(),"r"))){
Label1->Caption = "Cannot Open Read File";
exit(1); //実行を終了し,オペレーティングシステムに戻る
}
for(i=0;i<100;i++){ //ファイルから内容を読込む
//ファイルの終わりかどうか判断する
if(NULL == fgets(buff1,255,fp0)){
Label1->Caption = "Finish";
break; //for文をぬける
}
fprintf(fp0,"%s",buff1);
}
fclose(fp0);
0379デフォルトの名無しさんNGNG
>>378
> この操作をするにはbuff1+"a.txt"なんてすれば良いのかな?
良くないです。strcat() 使いましょう。
0380sageNGNG
strcpy(buff1 + strcspn(buff1, "\r\n"), "a.txt");
0381ikuNGNG
レスありがとうございます。
ちなみに3文字を+したい場合は
strcat(s1,s2);
strcat(s1,s3);
と2回やらなきゃいけないのでしょうか?
それともう一点,何で文字化けしていたのでしょうか?
0382デフォルトの名無しさんNGNG
>>381
> ちなみに3文字を+したい場合は
「+ する」というのは、意味が曖昧だから使わない方がいい。s2, s3 が指している
文字列を s1 が指している文字列に連結したい、ということだと思うが、それなら
>>381 のように 2 回 strcat() する以外に

char path[MAXPATH];
sprintf(path, "%s%s%s", s1, s2, s3);

なんて書く方法もある。(ファイルから読み込んでる場合には、改行文字を事前に
潰しておくことをお忘れなく)

> それともう一点,何で文字化けしていたのでしょうか?
それは正確に話すと、わりと面倒なんで俺はパス。とりあえずポインタと文字列
をキーワードに、書籍を読んでみたら、とだけ言っておきます。
0383ikuNGNG
>>382
ご指摘ありがとうございます。
これからはもっと注意します。
ポインタと文字列をキーワードに,わかりました。
もしお勧めの本がありましたら教えて下さい。
よろしくお願いします。m(_ _)m
それにしてもCって難しいですね。
プログラムが動く仕組みをよく理解していないと・・・・・
0384デフォルトの名無しさん ?NGNG
>>383
「プログラムが動く仕組み」どころか、
文字列のなりたちをきちんと理解してくれると いいなぁ。
C言語じゃなくても、他の言語でも共通の部分なので。
0385ikuNGNG
>>384
はい。ごもっともです。m(_ _)m
0386デフォルトの名無しさんNGNG
>>385
sage で書いてくれ。
0387デフォルトの名無しさんNGNG
>>385

そのメールアドレスって本物?
場をわきまえようね(^_^;)
0388デフォルトの名無しさんNGNG
>>387
でもさ、実際こういう風に晒したところでなにか問題ある?
mailto:[email protected]
0389デフォルトの名無しさんNGNG
>>388

うざいメールがイパーイ
売られる可能性もあるし。
0390Kusakabe YouichiNGNG
In article >>372, 372 デフォルトの名無しさん wrote:

> くさかべせんせえ、下は九九を表示するプログラムで、両方とも
> コンパイラは通るのですが、

そうですか。
0391Kusakabe YouichiNGNG
In article >>383, iku/383 <[email protected]> wrote:
> それにしてもCって難しいですね。

簡単ですよ。

> プログラムが動く仕組みをよく理解していないと・・・・・

それは他の似た言語でも同じでしょう。
0392デフォルトの名無しさんNGNG
#include <iostream>
int main(){
char c[20]="123abc";
char *p=&c[0];
char *a="aaa";
c[7]=100;
for (int i=0;i<20;i++){
printf("%d\n",c[i]);
printf("%d\n",&c[i]);
printf("%d\n",++p);
}
printf("%d\n",++p);
printf("%d\n",a);
printf("%d\n",++a);
return 0;
}
0393デフォルトの名無しさんNGNG
↑char *a="aaa"の部分ですが、
これはメモリのどこかに"aaa"という文字列定数が記憶されて
それへのポインタが入るってことでいいのでしょうか?
0394デフォルトの名無しさんNGNG
>>393

よい。
0395デフォルトの名無しさんNGNG
>>394
どうもありがとうございました!
0396Kusakabe YouichiNGNG
In article >>393, デフォルトの名無しさん/393 wrote:

> ↑char *a="aaa"の部分ですが、
> これはメモリのどこかに"aaa"という文字列定数が記憶されて
> それへのポインタが入るってことでいいのでしょうか?

そうですね。
0397デフォルトの名無しさんNGNG
>>395

この後にIn article君がうるさいことを言うだろうけど、無視してね。
0398デフォルトの名無しさんNGNG
for 文のネストって実際の業務では何重まで許されるんですか?
0399デフォルトの名無しさんNGNG
>>398

一回も許さない。
0400Kusakabe YouichiNGNG
In article >>398, デフォルトの名無しさん/398 wrote:

> for 文のネストって実際の業務では何重まで許されるんですか?

「業務では」ってのはとくにないでしょう。
Cの規格で許されているところまででは?
0401デフォルトの名無しさんNGNG
でも8重ネストとか見ると叩きたくなりませんか?
0402デフォルトの名無しさんNGNG
>>398
あなたは何重まで許せますか?
0403デフォルトの名無しさんNGNG
>>400
規格で認められていてもたとえば「プロジェクトのスタイルに反する」
という理由でリジェクトされる可能性はあるでしょう。
規格を知らない人間でもスタイルにはうるさいもんだし。
0404デフォルトの名無しさんNGNG
>>403
そういう人間とクサカベたんの対決が見てみたいなぁ。
0405Kusakabe YouichiNGNG
In article >>401, デフォルトの名無しさん/401 wrote:

> でも8重ネストとか見ると叩きたくなりませんか?

いいえ。
0406Kusakabe YouichiNGNG
In article >>403, デフォルトの名無しさん/403 wrote:

> >>400
> 規格で認められていてもたとえば「プロジェクトのスタイルに反する」
> という理由でリジェクトされる可能性はあるでしょう。

っていうか、プロジェクトごとにコーディング規約はちがうわけだから、
こんなところで一般論を聞いてもいみないのでは?

で、それを承知で聞いているのだから、
プロジェクトごとのコーディング規約のことではないと
思われる。
0407デフォルトの名無しさんNGNG
>>401
人間が書いたコードだと許せんが、コードジェネレータが吐いたコードなら
許す。
0408デフォルトの名無しさんNGNG
どのファイルの関数からもいじれるbool変数_endingをメインファイルのヘッダで
定義したのですが、次のようなエラーが出ました。
でもコンパイルは通って、ちゃんと動きますし、_endingの動作も意図した通りです。

>リンク中...
>gmain.obj : error LNK2005:
>"bool _ending" (?_ending@@3_NA) はすでに main.obj で定義されています
>draw.obj : error LNK2005:
>"bool _ending" (?_ending@@3_NA) はすでに main.obj で定義されています

以下はヘッダの定義部分です。
>#include <windows.h>
>#include "gmain.h"
>#include "draw.h"
>// -----------------------------------------------------
> bool _ending; // 終了フラグ

"gmain"ソースファイル内だけでいじっていますが、
"draw"ソースファイル内では参照も何もしていません。
コンパイラはVC++6.0です。このままほっておくとマズイのでしょうか。
0409デフォルトの名無しさんNGNG
>>408
main.h内で
extern bool ending;

main.cpp内で
bool ending;


で、みんなでmain.hをインクルード。
0410393NGNG
#include <iostream>
int main(){
int *a;
a=(int *)malloc(sizeof(int)*10);
a[5]=100;
for (int i=0;i<10;i++){
printf("%d\n",*a);
printf("%d\n",&a);
printf("%d\n",a);
a++;
}
return 0;
}
ワカワカメヨ。。。モウ
0411デフォルトの名無しさんNGNG
>>410
とりあえず、確保した領域初期化したら?
0412デフォルトの名無しさんNGNG
>>409
通りました!ありがとうございますです・・・。
課題○投げスンマセン。
0413デフォルトの名無しさんNGNG
とりあえず>>351の
>int a[3][3];において常に&a[0][3] == &a[1][0]は成り立つか。
が気になるんですが、どういうときに成り立たないんでしょう?
成り立つと思ってたんですが
0414393NGNG
#include <iostream>
int main(){
int *a;
int i;
a=(int *)malloc(sizeof(int)*10);
for (i=0;i<10;i++){
a[i]=i*3;
}
for (i=0;i<10;i++){
printf("%d\n",*a);
printf("%d\n",&a);
printf("%d\n",a);
a++;
}
return 0;
}
とりあえず初期化と。。。
int型へのポインタ型変数「a」っていう変数にmallocで確保したアドレスが入って・・・
*aで「a」に入ってるアドレスへ行く。
&aで「a」自身のアドレスを参照。
aで「a」に入ってるアドレスを参照。
という解釈でよろしいでしょうか?
でもa++してるのに&aの値が変わって行かないのはなぜなの?アカン。。。
0415デフォルトの名無しさんNGNG
>>414
ポインタ変数に++してるから。では。
0416デフォルトの名無しさんNGNG
int b; だったとしたら、
b++; ってしても &b の値は変わらないでしょ。

int *a; のときも一緒。
0417デフォルトの名無しさんNGNG
>>414
a++で代わるのは
変数aの値であって
aのアドレスではない。
0418393NGNG
>>415
あっどうもありがとうございました。
「a」自体のアドレスは変わらずに
中身が指すアドレスが++されていくからですね。
チョトワカッテキタ
0419393NGNG
>>416-417
どもありがとうございました。
なんだかわかってきたような気分です!!
0420デフォルトの名無しさんNGNG
>>408
_ から始まる識別子(厳密にはもうちょっと制限されるけど)は、処理系や
標準ライブラリが使うために予約されている。_ending はおそらく CRT の
スタートアップルーチンあたりで使われているものとコンフリクトしている
ものと思われ。

不幸なことになる可能性が高いから、とりあえず _ から始まるシンボルを
使うのはやめとけ。
0421デフォルトの名無しさんNGNG
ASCIIってどうよ。
0422デフォルトの名無しさんNGNG
>>420
ありがとうございます。
__FILE__とかですね(多分)。ちょっと目印に、と思ったのですが
アホでした。しかもなんだか危険極まりないカンジの予約語ですね・・・
名前のつけ方勉強しなおしますです・・・
0423デフォルトの名無しさんNGNG
ラテン8ってどうよ。
0424デフォルトの名無しさんNGNG
gccを2.95から3.02にしたのですが
環境変数を読んでくれなくて -I -L
オプションで逃げたのですが
今度はリンカが膨大なエラーを吐くので
(undefined reference _virtual_なんとか)
へこんでおります。

3.0はオブジェクトの出力形式も違うのでしょうか?
(こんなときに FAQ の mail-archive の cgi が止まってる-- >_<)
0425機種依存の勉強NGNG
486でビットフィールドはどういうふうに扱われますか?

struct {
 unsigned int a:8;
 unsigned int b:8;
 unsigned int c:8;
 unsigned int d:8;
} chars;

union {
 unsigned int r;
 struct chars c;
} unichars;

union unichars u;

u.r = 8; といれたときに u.c.d に入る?それとも u.c.a ?
gccは2.9.xです
0426デフォルトの名無しさんNGNG
>>424
3.0からC++のmangling schemeが変わってる。ライブラリもコンパイルしなおせ。
0427名無しNGNG
486はC言語を解するようになったのですか? by void風
実行してみればわかるだろハクチデスカ ┐(´ー`)┌ by むぎ茶風
0428機種依存の勉強NGNG
>>427
えーすみません

動かしました。わかりました。aに入りました。

野村監督 辞任だってさ
0429デフォルトの名無しさんNGNG
486はリトルなエンディアンさ。
0430デフォルトの名無しさんNGNG
俺もゆで卵はとんがってる方から食べるな。
0431デフォルトの名無しさんNGNG
>>430
え?
0432デフォルトの名無しさんNGNG
>>431
ビッグエンディアンとリトリエンディアンの由来を調べてみれ。
0433393NGNG
#include <iostream>
int main(){
int *a;
a=(int *)malloc(sizeof(int)*10);
free (a);
return 0;
}
これでちゃんとfreeされてます?

それはいいとして、
int型ポインタ変数aはmalloc確保されたアドレスの先頭しか
わからないですよね?
終わりはここ!ってのはわからないはず?なのに、
なぜちゃんと解放してくれるのでしょうか?
どこかにここからここまで確保しましたっていう情報が
記録されてるのでしょうか?それとも・・・
0434デフォルトの名無しさんNGNG
> どこかにここからここまで確保しましたっていう情報が
> 記録されてるのでしょうか?
これが正解。
ただし、移植性のある方法でそれを調べる方法はない。
0435424NGNG
>>426
ありがとうございます m(__)m お教えの通り自作のライブラリを
コンパイルしなおしたのですが、まだエラーが...

試してみると3.0のライブラリのみ使うプログラムは正常に
スタティックリンクできました。自作ライブラリをリンクすると
エラーみたいで…。
環境変数から無視される辺りから何か変ですよね。
オプションが正しく渡っていないのかも…。
0436デフォルトの名無しさんNGNG
>>433
実は公にされてはいませんが、
CPUにはラプラスの悪魔が仕組まれています。
0437デフォルトの名無しさんNGNG
自分でサイズ指定してるジャン。
0438393NGNG
>>434
それを管理しているのはOSなのでしょうか?
0439デフォルトの名無しさんNGNG
>>438
気にするな。
0440393NGNG
スミマセン
マエカラキニナッテタモンデ・・・
0441デフォルトの名無しさんNGNG
>>438
malloc() のソース読め。
0442デフォルトの名無しさんNGNG
保毛太郎

侍
0443デフォルトの名無しさんNGNG
printf("この〜木 何の木");

while (1) {
printf("気になる");
}
0444デフォルトの名無しさんNGNG
メモリ512Mの時代でいちいち気にすることではない。
0445393NGNG
>>441
ざっと目を通しただけですけども、
先頭アドレスとサイズで処理してるみたい(?)ですねぇ・・・。
どうもありがとうございました!
0446デフォルトの名無しさんNGNG
自分のOSはWIN95のPC-9821です
エスケープシーケンスを使いBorland C++ 5.5.1で
コンパイルをすると不具合がでます

例えば画面消去をしたくて
printf("\x1b[2J");
としても
[2J
↑のように出力されます

コンパイルしたEXEはDOS/Vのほうでは正常に動作します
何か対処方法はあるのでしょうか?
0447デフォルトの名無しさんNGNG
>>446
98版のWindowsってANSI.SYSついてないんだっけ?
ま、プログラミングとは関係ないから別の板で聞いた方がいいと思われ。
0448デフォルトの名無しさんNGNG
>>444
UMBも使え
0449446NGNG
ANSI.SYS入ってませんでした
でも一応 LSI C-86でコンパイルするとPC-98でも
エスケープシーケンスは正常に動作します
0450デフォルトの名無しさんNGNG
DEVICEHIGH=C:\WINDOWS\COMMAND\ANSI.SYS
0451446NGNG
>>447,450
ちょっと調べてみたらPC-98はANSI.SYSを組み込む
必要がないみたいでした
でも原因が特定できてよかったです。ありがとうございました

あとスレ違いスイマセン
0452デフォルトの名無しさんNGNG
ちょっとおしえてください。

char str[] = "あAAAA";
とやって
if (str[0] == 'あ')
とか
printf("%c", str[0]);
をやりたいのですが失敗します

mbchrcmpとかmbprintfとか無いのでしょうか?
0453デフォルトの名無しさん NGNG
strncmp
0454Kusakabe YouichiNGNG
In article >>452, デフォルトの名無しさん/452 wrote:
> char str[] = "あAAAA";
> とやって
> if (str[0] == 'あ')
> とか
> printf("%c", str[0]);
> をやりたいのですが失敗します

「失敗します」じゃあ「どうなったか」がわからないですね。

ちゃんとできるようになるには、質問とかのときに「ちゃんと現状を報告できる」
ことがまず必要ですよ(ちゃんとした質問にするためだけじゃなくて、自分の理解の
ためにも)

あと、この場合は環境の報告も必要ですね。
0455デフォルトの名無しさんNGNG
mbchrcmpって何? ぶびちぅ??
0456デフォルトの名無しさんNGNG
>>454
すいません、ちょっと専門的な話をしてるので黙っててもらえますか
もし話に入れなくて気分を害されたならごめんなさい
0457デフォルトの名無しさんNGNG
「」で囲むのは、何か意味があるんですか?
0458Kusakabe YouichiNGNG
In article >>456, デフォルトの名無しさん/456 wrote:

> >>454
> すいません、ちょっと専門的な話をしてるので黙っててもらえますか

「専門的」な質問ですね ;)
0459デフォルトの名無しさんNGNG
VB厨なんかなmbchrcmpて、スゲー気になる (w
0460Kusakabe YouichiNGNG
In article >>457, デフォルトの名無しさん/457 wrote:
> 「」で囲むのは、何か意味があるんですか?

そういうのはCの文法にないですね :)

ヒント: %lcについては415ペイジに解説があります。
0461デフォルトの名無しさんNGNG
MultiByteだよ -> MB...
VB厨には違いないが
0462Kusakabe YouichiNGNG
In article >>459, デフォルトの名無しさん/459 wrote:
> VB厨なんかなmbchrcmpて、スゲー気になる

っていうか、てきとーな入門書でも見ればいいのにとは思う。
0463デフォルトの名無しさんNGNG
wchar_t wstr[] = L"あAAAA";
とやって
if (wstr[0] == L'あ')
とか
printf("%lc", wstr[0]);
をすればいいのでは?
0464デフォルトの名無しさんNGNG
ふつう「あ」は2バイト、charは1バイト。
0465452NGNG
char*の指しているアドレスの文字(全角&半角)が知りたかったんです。
半角1バイト、全角2バイトは知ってましたが、どうすればよいか分からなかったので。

463さんありがとうございます。
出来ました。
Lを付けるのは知りませんでした。もっと勉強します。
0466デフォルトの名無しさんNGNG
>454
日本語は2バイトだから駄目、どうしてもそうしたいなら
if(str[0] == "あ"[0] && str[1] == "あ"[1])
0467452NGNG
"あ"[0] "あ"[1]なんてできるとは知りませんでした。
いいこと教えてくれて有難うございます。
0468Kusakabe YouichiNGNG
In article >>463, デフォルトの名無しさん/463 wrote:
> wchar_t wstr[] = L"あAAAA";
> とやって
> if (wstr[0] == L'あ')
> とか
> printf("%lc", wstr[0]);
> をすればいいのでは?

そういう教え方では本人のためにならないような(^^;
■ このスレッドは過去ログ倉庫に格納されています