C言語なら俺に聞け( ..
[2ch|▼Menu]
49:デフォルトの名無しさん
08/06/02 13:48:38
>>48
あなたがお使いのコンパイラはあくまで>>45のいうような動作をするだけで
別のコンパイラだと違った結果を出すこともあると覚えて置いてください。

50:デフォルトの名無しさん
08/06/02 13:51:34
>>47
そういう言い方すると単に評価の順序が不定みたいな感じがするが、
>>41のコードはコンパイルすら通らない可能性もあるし、実行時にエラーが発生する可能性もある。

51:デフォルトの名無しさん
08/06/02 13:52:18
>>49
ありがとうございます
>>46様の言われている未定義動作と、言うのはコンパイラ別に判断される動作、ということなのですね


52:デフォルトの名無しさん
08/06/02 13:53:04
>>42
副作用完了点の間で同じ値を二度変更するのは常に未定義である。
未定義であるとは、その結果 ど ん な こ と が 起きても、
例えばパソコンが壊れるようなことがあったとしても、
規格もコンパイラもいっさい責任を持たないということである。

一般に言ってそのようなコードを書くことはまったく推奨されない。
少なくとも、全てを自己責任で行わなくてはいけない。

53:デフォルトの名無しさん
08/06/02 13:54:32
「規格が明確に定義していない」には3種類あって、以下のように定義されている。

・処理系定義(implementation defined)の動作
どう動作するかを実装が選択する。そのプログラムがコンパイルできないというのは許されない。
(この構成概念を使ったプログラムは誤りというわけではない。)
(実装が)何を選んだかは(コンパイラの作者が)文書にしておかなければならない。
規格が合法な動作をいくつか用意していてそこから選ぶことができるかもしれないし、
必要条件をとくに課していないかもしれない。

・未規定(unspecified)の動作
処理系定義の動作に似ている。ただし、どういう動作を選んだかは文書にする必要がない。

・未定義(undefined)の動作
本当に何が起きても不思議はないことを意味する。規格は何の必要条件も課さない。
コンパイルできないかもしれないし、誤った動きをするかもしれないし
(クラッシュしたり黙って誤った結果を出したり)、
あるいはたまたまプログラマの意図したとおりの動きをするかもしれない。


以上、CFAQより抜粋


54:デフォルトの名無しさん
08/06/02 13:56:00
>>51
違う
「やってはいけないこと」の類

55:デフォルトの名無しさん
08/06/02 13:57:28
まあ、勉強用の課題でだされたのかもしれないけど
普通にプログラミングしてて

printf("j++ * j++結果:%d\n", (j++) * (j++));

は気持ち悪いと思ってまず組まないけどなw

56:デフォルトの名無しさん
08/06/02 18:03:09
C言語なら俺に聞け(入門篇) Part 28
スレリンク(tech板:992-番)

URLリンク(www.kk.iij4u.or.jp)
ここを参考にしたのですが先頭の2バイトに設置されている"BM"が曲者で
ヘッダも14バイトなのでせめて2バイト予備で入れてくれればいいのに・・・
という状況で・・・・

自分のプログラムで使う構造体なら考慮して作りますけどすでにある
共通のフォーマットだとそうもいかなくて無理やりやってるんですよねorz

57:デフォルトの名無しさん
08/06/02 18:03:25
>>前スレ992
gcc なら
#pragma pack(1)
でおk

58:992
08/06/02 18:04:29
>>57
ある構造体だけを指定してpack制御するとかは無理ですかね?

59:デフォルトの名無しさん
08/06/02 18:08:01
>>58
#pragma pack(2)
struct ほにゃらら;
#pragma pack(0) // 元に戻す

60:デフォルトの名無しさん
08/06/02 18:10:09
>>56
struct Foo {unsigned char c[14];}でも用意して、適宜変換する関数群でも用意しておけばよかろ。
static inline unsigned long getBfSize(const Foo f)
{
union {
unsigned long u;
unsigned char c[4];
} v;
v.c[0] = c[2]; v.c[1] = c[3]; v.c[2] = c[4]; v.c[3] = c[5];
return v.u;
}
位の関数なら、最適化で消えてなくなるだろ。

61:デフォルトの名無しさん
08/06/02 18:12:26
#pragma pack(push, 1)
struct ほにゃらら;
#pragma pack(pop) // 元に戻す

つーのもあったような

62:デフォルトの名無しさん
08/06/02 18:15:53
>>61
そっちのほうが行儀がいいな

63:デフォルトの名無しさん
08/06/02 22:01:24
>>20
あなた、感覚がかなり可笑しいよ。アセンブラ勉強したら?
成り下がるって事ではなく内部からすれば Call by Value の方が処理多くなるでしょよ。
一般の言語から C 系に来ると逆転するんだよね。

64:デフォルトの名無しさん
08/06/02 22:20:11
3人のテストの点数がそれぞれ90,45,82(int型)だった。3人の平均点を実数(float型)で求め、少数点以下1桁まで出力するプログラムを書け。

の作成をして頂けませんか‥‥??
手元にemacsがなく、しかし、答え合わせをしたく思います‥!!

65:デフォルトの名無しさん
08/06/02 22:20:44
規格の仕様と実装の区別がついてない方はお引取りください

66:デフォルトの名無しさん
08/06/02 22:21:26
>>64
教えて欲しいのではなく宿題を丸投げしたいならこちらへ。
 C/C++の宿題を片付けます 108代目
 スレリンク(tech板)

67:デフォルトの名無しさん
08/06/02 22:25:07
>>64
脳内にCインタプリタを構築して、神と鉛筆を持って脳内ステップ実行してみろ。
机上デバッグといって昔はみんなそうしてた。

68:デフォルトの名無しさん
08/06/02 22:26:37
>>67
懐かしいなw

学校にコンパイラすらなくてマシン語手打ちしてたときは
そんな感じだったよw

69:デフォルトの名無しさん
08/06/02 22:32:21
>>64
サンプル・・・だけどあえて罠が入ってる。

int a,b,c,d;
float e;
a = 90;
b = 45;
c = 82;

c = a + b + c;
e = c/3;

(ここに標準出力)


70:デフォルトの名無しさん
08/06/02 22:33:28
その程度のコードでemacsは必要ないな

71:デフォルトの名無しさん
08/06/02 22:33:37
>>64
emacsでないと書けないというのは奇妙な話だ。
君のコンピュータにはメモ帳がないのか?

72:デフォルトの名無しさん
08/06/02 22:35:34
Cと思わせてemacsだったのか

73:デフォルトの名無しさん
08/06/02 22:35:35
文脈から外人の気配を感じる
君のソースをここに書いてみて
もし間違いがあれば指摘してもらえるよ

74:デフォルトの名無しさん
08/06/02 22:36:09
>>65
あなたは実引数に配列識別子を指定した場合、
関数に対してポインタに成り下がったものが渡ると思いますか?
それとも、配列の先頭アドレスを指すポインタに変換された後、
そのポインタが指すアドレスが渡ると思いますか?

75:デフォルトの名無しさん
08/06/02 22:48:54
>>74
お引取りください

76:デフォルトの名無しさん
08/06/02 22:49:52
人の話を論理的に解釈できない奴になに言っても無駄だよ
放置しろ

77:デフォルトの名無しさん
08/06/02 22:49:55
おとこわりします

78:デフォルトの名無しさん
08/06/02 22:57:41
>>74
その2つは、同じことを言い換えただけだと思います。

79:デフォルトの名無しさん
08/06/02 23:09:33
>>78
むやみに触ると火を吹くよ><

たぶん、たぶんなんだけど、後者だと思う。
C言語は値渡しだから、ポインタ変数を引数に指定した場合に、
それ自体を関数側で操作する事はできず、ポインタ変数の値である
番地しか渡せない。つまり、ポインタ変数を渡したい場合は、
そのポインタ変数が格納されているアドレスを渡さないといけないって
いいたいんだと思う。

こんがらがってきたorz
…噴火したらゴメンヨ。

80:デフォルトの名無しさん
08/06/02 23:10:55
気を取り直して、、、

>>69
ありがちな罠ワロスw

81:デフォルトの名無しさん
08/06/02 23:12:41
罠とは関係ないけどdはなんだったんだw

82:デフォルトの名無しさん
08/06/02 23:29:11
Dだって?
忘れろ
忘れるんだ
2.0なんか出てないんだ

83:デフォルトの名無しさん
08/06/02 23:32:45
「プログラムと同じフォルダ内のbmpファイル(256色)(200*300pix)をプログラム実行
時に読み込ませ,1pixごとにそのRGB値を調べさせてCSV形式で書き出すプログラム 」
というプログラムを「C/C++の宿題を片付けます」で作っていただいたのですが、RGB値を読み込むことが出来ません。どうすれば読み込めるようになるか教えてください。
以下のプログラムが作っていただいたプログラムになります。
URLリンク(kansai2channeler.hp.infoseek.co.jp)


84:デフォルトの名無しさん
08/06/02 23:38:32
なぜ
ここで
聞く

85:デフォルトの名無しさん
08/06/02 23:55:11
つーかGetPixel使ったほうが楽だよ

86:デフォルトの名無しさん
08/06/03 00:05:00
>>85
GetPixelはこのプログラミングにそのまま使っても問題ないのでしょうか?
あと流れとしては

GetPixelでpixel指定をする。

指定したPixelでRGB値を読み込む。

これをfor文で繰り返す。

87:デフォルトの名無しさん
08/06/03 00:11:19
課題かなんかで使っちゃダメって言われてないなら問題ないでしょ

int i,j;
COLORREF savecolor[XSIZE][YSIZE];

for(i = 0; i < XSIZE; i++){
  for(j = 0; j < YSIZE; j++){
    savecolor[i][j] = GetPixel(i, j);
  }
}

あとはCSV形式にするだけ

88:デフォルトの名無しさん
08/06/03 00:20:43
>>87
私自身の実験解析手段なので、使わせていただきます。
あと、これを用いた時にRGB値を調べるのによいプログラミングはどういったものなのでしょうか?
RGB値を読み込むものを探したらいろいろと出てきてどれを使えばよいのか分からないのですが。
お手数おかけします。


89:デフォルトの名無しさん
08/06/03 00:27:21
ごめん
>>87のGetPixel引数1個足りないわ
HDCにビットマップをロードしとかないとダメだった
RGB値を調べるというのは意味がちょっと分からないけど
GetRValue, GetGValue, GetBValue でCOLORREF型からRGBが取得できる

90:デフォルトの名無しさん
08/06/03 00:27:45
ビットマップって意外と面倒なんだよなw
縦のライン数が正か負で情報の保存されてる方向がちがうんだよなw

91:デフォルトの名無しさん
08/06/03 00:38:02
>>89
HDCは普通に画像を読み込んで、それをFILEのポインタで用意したものを使ったらいいのでしょうか?
あとざっと調べてみたのですが、GetRValue, GetGValue, GetBValueは例えば
color=getpixel()
で読み込んだものを
r[i][j]=GetRValue(color)
見たいな感じで組んでいけばいいでしょうか?

92:デフォルトの名無しさん
08/06/03 00:38:47
まじめにBMPをサポートするとこんな感じ?
URLリンク(www.kk.iij4u.or.jp)
ここの下のほうにあった
URLリンク(www.kk.iij4u.or.jp)

93:デフォルトの名無しさん
08/06/03 00:50:38
>>92
ありがとうございます。このデータを参考にもう一度プログラムを練ってみようと思います。
本当にありがとうございました。

94:デフォルトの名無しさん
08/06/03 00:57:38
1から100の合計を求め、改行を表示するプログラムを教えてください

95:デフォルトの名無しさん
08/06/03 01:00:11
おせっかいかもしれませんが、ついでなので最適化もしておきました。

#include <stdio.h>
int main(){puts("");return 0;}

96:デフォルトの名無しさん
08/06/03 01:03:07
申し訳ございませんが、合計は返りちでお願いします

97:デフォルトの名無しさん
08/06/03 01:07:46
教えて欲しいのではなく宿題を丸投げしたいならこちらへ。
 C/C++の宿題を片付けます 108代目
 スレリンク(tech板)


98:デフォルトの名無しさん
08/06/03 01:15:54
あ、気分を害しちゃいましたか?
宿題ではないんですけどね

99:デフォルトの名無しさん
08/06/03 01:21:32
int ReSum(int min, int max)
{
  int sum = 0;

  for(; min < max; min++)
    sum += min;

  printf("\n");  

  return sum;
}

100:デフォルトの名無しさん
08/06/03 01:23:59
エレガントですね
ありがとうございます
これからもちょくちょくお邪魔することにしました

101:デフォルトの名無しさん
08/06/03 06:12:04
#include <stdio.h>
#include <ctype.h>

void Oomoji( char *st );

void main()
{
char *moji = "abc";
char moji2[] = "abc";
Oomoji(moji2);
}
//大文字に変換する関数
void Oomoji( char *st )
{
int i = 0;

while( *(st+i) != '\0' ) {
*(st+i) = toupper( *(st+i) );
i++;
}
printf( "%s\n", st );
}
すいません、質問したいのですが変数moji2だと、ちゃんと大文字に変換できる
のですが、ポインタ変数mojiだと変換できないのですが、なぜなのか教えて
もらえないでしょうか、お願いします。開発環境はVisual C++です。

102:デフォルトの名無しさん
08/06/03 06:23:57
mojiのポインタ内に入ってるのはchar型じゃなくてconst char型だから書き換え不可

C++じゃなくてC言語だと書き換えも可能だけど絶対やらない事

103:デフォルトの名無しさん
08/06/03 06:38:17
>>102
ありがとうございます。

104:デフォルトの名無しさん
08/06/03 07:49:47
>>102
つまりchar *型で宣言した文字列は絶対にconst charになるので、
101のような書き換えは、するなと言うことなんですかね?

105:デフォルトの名無しさん
08/06/03 07:57:49
ポインタと配列は同じだと思ってる人多いけど気を付けた方がいい
それと配列を関数を通してポインタにキャストするのも、あまり好ましくはないかな・・・
void Oomoji2( char sz[], size_t sz )
微妙に意味合いが変わるしね
ついでに、strncpyみたいに配列サイズの指定も推奨

106:デフォルトの名無しさん
08/06/03 09:05:56
>>101
コンパイラによっては、文字列リテラルは読み取り専用領域に用意される
(オプションで動作を切り替えられるコンパイラもある)

>char *moji = "abc";

この場合、読み取り専用領域に確保された文字列"abc"を指すように、ポインタmojiを初期化している
mojiは"abc"を指しているだけで、その指す先は読み取り専用領域だから、書き換えられない

>char moji2[] = "abc";

この場合、"abc"という内容で配列moji2を初期化している
どこか別の領域を指しているわけではなく、moji2自身に文字列の内容が含まれているので、書き換えられる

107:デフォルトの名無しさん
08/06/03 09:31:12
>>106
どうも、ありがとうございました。理解できたと思います。

108:デフォルトの名無しさん
08/06/03 10:01:10
scanf関数での入力に手を焼いているけど、一番無難な入力関数ってなんだろ?getchar関数だと、処理速度が気になるし。

109:デフォルトの名無しさん
08/06/03 10:05:07
fgets

110:デフォルトの名無しさん
08/06/03 10:33:56
fgets(buff,BUFF_SIZE,stdin);
fflush(stdin);


111:デフォルトの名無しさん
08/06/03 10:35:11
fflush(stdin)は処理系依存って怒られるぞw

112:デフォルトの名無しさん
08/06/03 13:55:50
文字列を配列30個作り、奇数15の配列を順に表示するのはどうやんの?
今日変な課題出された。

113:デフォルトの名無しさん
08/06/03 13:58:49
for(i=1; i<30; i+=2) puts(str[i]);

114:デフォルトの名無しさん
08/06/03 13:59:05
>>112
奇数15というのは文字列の配列30個のうちの奇数番号の配列15個でOK?

115:デフォルトの名無しさん
08/06/03 14:03:25
>111
処理系依存っつか未定義な

116:デフォルトの名無しさん
08/06/03 14:05:40
番号は0スタートでいいんだよね?念のため

117:デフォルトの名無しさん
08/06/03 15:11:05
変な課題だな。


118:デフォルトの名無しさん
08/06/03 15:26:06
#include <stdio.h>
#include <stdlib.h>

#define LIMIT 50 /* スタックに入る数の最大値 */

typedef int a ; /* 真偽値の型 */

int StackArray [LIMIT] ;
int top ; /* スタックの先頭を指す */

void push (int x) ; /* 関数のプロトタイプ宣言 */
int pop (void) ; /* 関数のプロトタイプ宣言 */

a push_1 (void) ; /* 関数のプロトタイプ宣言 */
a pop_1 (int n) ; /* 関数のプロトタイプ宣言 */
void error (void)
{

}

int main(int argc, char **argv)
{
int order, x, y ;
top = 0 ;

119:デフォルトの名無しさん
08/06/03 15:26:45
while (1)
{
printf ("\n現在のデータ数:%d\n", top) ;
printf ("現在のスタックの状態:") ;
{int i ; for (i=0; i<top; ++i) printf ("%d ", StackArray[i]) ;} printf ("\n") ;

if (push_1 ()) printf ("(1) push ") ;
if (pop_1 (1)) printf ("(2) pop ") ;
printf ("(3) finish ") ;
if (pop_1 (2)) printf ("(4) + (5) − (6) × ") ;
printf (">") ;

scanf ("%d", &order) ;

switch (order)
{
case 1: if (push_1 ()) { printf ("input data: ") ; scanf ("%d", &x) ; push (x) ;} else error () ; break ;
case 2: if (pop_1 (1)) { printf ("%d\n", pop ()) ;} else error () ; break ;
case 3: return EXIT_SUCCESS ;
case 4: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x+y) ;} else error () ; break ;
case 5: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x-y) ;} else error () ; break ;
case 6: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x*y) ;} else error () ; break ;
default: error () ;
}
}
}


120:デフォルトの名無しさん
08/06/03 15:27:07
a push_1 (void)
{
return top < LIMIT ;
}
void push (int x)
{
StackArray [top] = x ;
top = top++ ;
}

a pop_1 (int n)
{
return 0 <= top-n ;
}
int pop (void)
{
top = top-- ;
return StackArray [top] ;
}


121:デフォルトの名無しさん
08/06/03 15:33:36
逆ポーランド記法のプログラムを作ってて、1〜9の範囲の整数を入力したいんですけど、どこに入れたらいいですか?
また、1〜9の範囲の整数を入力するプログラムって
#include<stdio.h>
int main(void)
{
int x;
if(x>0 || x<10)
{
printf("1〜9の整数です\n");
}
else
{
return 0;
}
}

こんな感じでいいですか?

122:デフォルトの名無しさん
08/06/03 15:45:10
だめです

123:デフォルトの名無しさん
08/06/03 15:53:18
>typedef int a ; /* 真偽値の型 */
アホなことやるな


124:デフォルトの名無しさん
08/06/03 15:53:55
#include <stdio.h>

void main()
{
int year, month, day, weekday;
for (year = 2001; year <= 2100; year++){
for (month = 1; month <= 12; month++){

weekday = ((year + year/4 - year/100 + year/400 + (13*month+8)/5 + 13) % 7)+8;
if (weekday == 13)
printf("%4d年 %2d月 %2d日\n",year, month, weekday);
}
}
}
この実行結果の13日の金曜日の個数はどうやって求めればいいですか?

125:デフォルトの名無しさん
08/06/03 15:55:42
>>118
なんか全体的に気色悪い書きかただなぁ

126:デフォルトの名無しさん
08/06/03 15:57:21
>>122
どこがダメですか?教えてください

127:デフォルトの名無しさん
08/06/03 16:04:02
とりあえず
top=top++;
top=top--;
これ未定義


128:デフォルトの名無しさん
08/06/03 16:09:27
>>121
>>118-120までで出来てるんじゃないのか?(>>127の間違いあるけど)
それとも自分で書いたソースじゃないのか?

とりあえず1〜9を判定したいなら scanfでxに値を入れてから if(x>0 && x<10) だ

129:デフォルトの名無しさん
08/06/03 16:14:38
>118
・真偽型なんか宣言するな
・スタックの状態を判定する関数の名前をもう少し工夫しろ
・while(1)よりも、orderを初期化した上でdo{ ... }while(order!=3); のほうが構成的に綺麗
気になるのはそんなとこか

130:デフォルトの名無しさん
08/06/03 16:19:08
>>126
x に値が入っていない
条件は || じゃなく &&
return は else の外に出せ(elseは必要ない)

131:デフォルトの名無しさん
08/06/03 16:26:11
>>124
変数に記録でもすれば?

132:デフォルトの名無しさん
08/06/03 18:04:59
#include<stdio.h>
int main(void)
{
int x;
scanf("%d", &x);
if(x>0 && x<10)
{
printf("1〜9の整数です\n");
}
return 0;
}

これでいいですか?

133:デフォルトの名無しさん
08/06/03 18:14:47
OK

134:デフォルトの名無しさん
08/06/03 19:21:21
C言語でミリ秒待たせるプログラムですが
みなさんのお薦めで教えて
簡単なヤツがいいです

135:デフォルトの名無しさん
08/06/03 19:23:44
>>134
DOSならSleep
Linuxならusleep

136:デフォルトの名無しさん
08/06/03 19:47:24
Sleep()がコンパイラにダメだと言われました、
ミリ秒待たせるにはどうしたらいいでしょうか(T_T)
sleepとか色々な綴りもやりました(;_;)

137:デフォルトの名無しさん
08/06/03 19:54:08
gettimeofdayとnanosleep

138:デフォルトの名無しさん
08/06/03 19:54:15
>>136
Cの標準関数じゃなくAPIになるから、環境をかけ。OSとコンパイラの種類とバージョンだ。

139:デフォルトの名無しさん
08/06/03 20:02:02
要素数noであるint型の配列vcの要素の最小値を返す関数
int min_of(const int vc[],int no)の作成の仕方を、どなたか教えてもらえませんか?



140:デフォルトの名無しさん
08/06/03 20:08:53
int min_of(const int vc[],int no)
{
  /* 必要な変数を宣言 */

  /* 最小値を記憶する変数にvcの最初の値を入れる */

  /* カウンタを1から初めてno未満であるあいだ1ずつ増やしながらループし */
  {
    /* vcのカウンタに対応する位置の値と、
      最小値を記憶している変数の値のどちらが小さいか調べ、
      その小さいほうを最小値を記憶する変数に格納する */
  }

  /* 最小値を記憶した変数をreturnする */
}

141:デフォルトの名無しさん
08/06/03 20:13:22
>>136
#include <Windows.h>

142:デフォルトの名無しさん
08/06/03 20:15:37
いつも思うんだが <widows.h>の hってなんの略?

143:デフォルトの名無しさん
08/06/03 20:16:29
header

144:デフォルトの名無しさん
08/06/03 20:16:30
>>142
ヘッダーのh
拡張子だよ

cソースの場合はxxx.c

145:デフォルトの名無しさん
08/06/03 20:17:16
最近の学生はヘッダという言葉を知らんのか

146:デフォルトの名無しさん
08/06/03 20:19:09
>>143
>>144
>>145
あ、ヘッダーだったのか
ありがとう

147:デフォルトの名無しさん
08/06/03 20:27:35
いいかい?これはおまじないだから忘れないようにね!
#include<stdio.h>

とか教えられたんじゃない?
スタジオドットエッチ、とか発音してそうな雰囲気だよー

148:デフォルトの名無しさん
08/06/03 20:30:21
でも本当に最初の最初はおまじないって教わった事を思い出した
まあ、最初からヘッダファイルがどうとかこうとか言ってたら中々始まらないしなぁ

149:デフォルトの名無しさん
08/06/03 20:32:14
まあな。
ちょっとなれたころに
#include<stdio.h>
なんかをはずしてみると、今まで使えてた関数が
コンパイルエラー起すでしょ、とか言って教えれるんだけどな。

150:デフォルトの名無しさん
08/06/03 20:33:09
最初からできるわけないもんな。
ファイル分割とかしてみてえと思って何回挫折したことか。懐かしいわぁ

151:デフォルトの名無しさん
08/06/03 20:33:25
#include <cstdio> とか h のないのを見かけるのですがあれは何ですか?

152:デフォルトの名無しさん
08/06/03 20:33:28
stdio.hを外してコンパイルエラーが出る関数ってのは難しいな。
FILE外したら関数以前にエラーが出るからなぁ。

153:デフォルトの名無しさん
08/06/03 20:34:08
>>151
それはすれ違い。

154:デフォルトの名無しさん
08/06/03 20:35:30
>>152
ん?極端に言うと、stdio.h無しだと何もコンパイルできない、と言っている?

155:デフォルトの名無しさん
08/06/03 20:38:24
>>154
逆。大抵の関数はエラーにならない。

156:デフォルトの名無しさん
08/06/03 20:40:39
stdio.h
stdlib.h
まあ、この二つをググッて調べてみるといいよ。
どういう関数が使えるようになるかわかる

157:デフォルトの名無しさん
08/06/03 20:45:52
>>155
やってみたら警告で済ませてくれた。
コンパイラやさしいな!

158:デフォルトの名無しさん
08/06/03 20:46:41
何の警告が出たんだ?

159:デフォルトの名無しさん
08/06/03 20:46:42
実は簡易的なHTMLの<この中の内容>を取り出す関数を作ろうと思っているのですが、
html->nextはHTMLの内容
#define BODY_SIZE 214
/* <>の切り出し */
html->body = (char *)malloc((size + 1) * sizeof(char));
if(html->body == NULL) goto END;

char *tmp;
while(*html->next++ != '<' && *html->next != '\0');
for(int len=0; html->next[len] != '\0'; len++){
if(html->next[len] == '>'){
html->body[len] = '\0';
break;}
if(len >= size - 1){
size += BODY_SIZE;
tmp = (char *)realloc(html->body,size);
if(tmp != NULL)
html->body = tmp;
else
goto END;}
html->body[len] = html->next[len];
}
HTMLの<>内を取得していくにあたり、動的なヒープ領域が足りなくなれば、
reallocを使って拡張し、また取得していく、という処理なのですが、
コードが複雑になり、非常に読み難いものになってしまい、
これをもっと簡潔には出来ないものでしょうか?

160:デフォルトの名無しさん
08/06/03 20:48:10
>>158
printfは組み込み関数じゃないよって警告。

161:デフォルトの名無しさん
08/06/03 20:50:11
>>159
それこそ線形リストがいいんじゃね?

162:デフォルトの名無しさん
08/06/03 20:55:18
>>161
今は>>159のコードを簡潔にしたいです。

163:デフォルトの名無しさん
08/06/03 20:55:53
あー、printfは使うのね

164:デフォルトの名無しさん
08/06/03 21:02:09
>>163
てか、各種ライブラリを使わずに使える関数って何があるの?
read と write は知ってるんだけど

165:デフォルトの名無しさん
08/06/03 21:09:33
>>159
そのソースの全体的な思想が分からないからなんともいえないんだけど
'<'から、次に見つかる'>'までがとにかく取れればいい、というのであれば
strposとかでキュッキュすればいいんじゃないかな。
<<>とか<hoge foo=">">とか無視していいならね。

166:デフォルトの名無しさん
08/06/03 21:11:26
>を多用しているソースは苦手だなw

167:デフォルトの名無しさん
08/06/03 21:14:40
環境はVS2005、Windowsなのですが、
strposをMSDNで調べましたが、見つかりません。

168:デフォルトの名無しさん
08/06/03 21:18:11
>>167
アイヤー。ごめん。strposはphpですた。
Cだとstrstr?

169:デフォルトの名無しさん
08/06/03 21:21:46
>>168
はい

170:デフォルトの名無しさん
08/06/03 21:23:00
>>168
なるほど、
ではreallocの部分は簡潔になりますでしょうか?

171:デフォルトの名無しさん
08/06/03 21:23:59
コピーの開始地点と終了地点がわかってから一気にmalloc()すれば
realloc()必要ないでしょ。



172:デフォルトの名無しさん
08/06/03 21:31:27
>>171
strstrで二点間(<>)の出現場所を計算して
mallocする、ということでしょうか?
ではstrstrを使わない場合で
>>159のreallocの部分を簡潔にするためにはどうすればいいでしょうか?

173:デフォルトの名無しさん
08/06/03 21:33:07
>>172
双方の出現場所が分かれば必要なサイズが分かるでしょ?
んでmalloc。
出現場所を調べる部分を簡潔にしたかったのでstrstr案を
出したわけでして、なぜ却下されたのだろう。ふしぎ!

174:デフォルトの名無しさん
08/06/03 21:34:54
>>172
なぜstrstr()やらstrchr()を使わない?

サイズが事前にわからないのならrealloc()するのは仕方ない。それが嫌
ならコピー元のhtml->nextの残りサイズと同じサイズをmalloc()してお
くしかない。
Cではこのへんが限界だよ。C++ならもっとすっきり。



175:デフォルトの名無しさん
08/06/03 21:37:47
>>174
strchr!思い出させてくれてありがとう。
indexofとかじゃなかったっけ?とかせっせと探してたんだw

176:デフォルトの名無しさん
08/06/03 21:38:46
とゆーか構造体htmlの仕様がなんか怪しくね

177:デフォルトの名無しさん
08/06/03 21:40:20
単にソースをすっきりさせるだけなら、size を html->body_size にして、
bool html_ensure_capacity(html_t *html, size_t new_size) {
void *tmp;
if (new_size < html->body_size-1) return true;
html->body_size += BODY_SIZE;
tmp = realloc(html->body, html->body_size);
if (tmp == NULL) return false;
html->body = tmp;
return true;
}
で、html_ensure_capacity(html, len);を呼ぶ。


178:デフォルトの名無しさん
08/06/03 21:41:42
>>173
私が先程聞いたのは、strstrを使わない場合に
>>159のコードのreallocを簡潔にする方法は無いか、という事です。
却下ではなく、場合の話です。
新しく聞いている訳で、あなたが教えてくれたstrstrを使う案を退けたつもりはありません。

179:デフォルトの名無しさん
08/06/03 21:42:52
簡潔という言葉が一体何を意味するのかがいまいち判然としないが、たぶん無い

180:デフォルトの名無しさん
08/06/03 21:44:25
俺だったら内容コピーしたりせずに先頭を示すポインタと長さを表す変数で済ませるね

181:デフォルトの名無しさん
08/06/03 21:46:22
あ、boolとか書いちゃったよ。てへ☆


182:デフォルトの名無しさん
08/06/03 21:47:23
本当に簡潔に済ませたいならreallocなんか使わずに済む方法を考えること
見たところファイルを全部メモリにロードしてるようだし、
範囲確定してから戻ってmalloc & strncpyすればいいじゃない

183:デフォルトの名無しさん
08/06/03 21:48:06
ではとりあえず
>>179
>>180
>>168
で試していきます。では

184:デフォルトの名無しさん
08/06/03 21:48:40
>>178
あ、タグを見つける部分を簡潔にするのと
realloc周りを簡潔にすることのどちらかしか行わないのね。
両方すればいいのにな、と思っただけですスミマセンスミマセン。

185:デフォルトの名無しさん
08/06/03 21:51:16
短い=簡潔
と思っているフシがあるのかな?
goto使ってたり、}の場所が、とか。

なんか、いろいろ違和感を感じるコードだなって思うわ。
とりあえず試行錯誤しながらがんばって成長してくだされ。

186:デフォルトの名無しさん
08/06/03 21:53:51
構造体の仕様とか名前付けのセンスとかでいろいろ察してしまう
個別のタグ内容を割り当てる構造体にファイル全体へのポインタを含めて
そこからデータをコピーしてくるってのは正直気色悪い

187:デフォルトの名無しさん
08/06/03 21:56:02
>>186
あなたが気持ち悪くならない方法を教えて下さい。

188:デフォルトの名無しさん
08/06/03 21:57:02
まあタグ以外の内容がいらないなら一つ一つバラしてコピーした後に
ファイル全体のバッファを捨てることになるんだろうけど
ふつーテキストと合わせてなんかやるよね

189:デフォルトの名無しさん
08/06/03 21:58:33
>187
ファイル全体のバッファ(のどこか)を指しているポインタは独立で用意して関数の引数で渡す
だけ

190:デフォルトの名無しさん
08/06/03 21:58:47
>>186
まだ成長途中なんだなあって思えてほのぼのするよね。

自分が昔書いたコード見たら気持ち悪い、というか、
なんでこう書いちゃったのwwって思う場所がよく見つかる

191:デフォルトの名無しさん
08/06/03 22:04:14
>>189
その様にした理由を教えて下さい。

192:デフォルトの名無しさん
08/06/03 22:06:49
>191
気色悪いから

193:デフォルトの名無しさん
08/06/03 22:10:36
>>192
論理的理由を聞いている訳ですが、

194:デフォルトの名無しさん
08/06/03 22:11:23
>193
ない

195:デフォルトの名無しさん
08/06/03 22:24:34
>>193
経験で分かるようになるよ。
「気持ち悪い」っていう感覚ってかなり重要だよ。

196:デフォルトの名無しさん
08/06/03 22:45:12
C言語なんだけど

終了しますか?(Y/N)とか、終了(1)
継続(0)とか、入力をさせる。
んで入力値をscanfで取って判断してるんだけど、
scanfって直前のEnterとか認識不能なコードをストリームに
残しておくとのこと

おかげでバグだらけで困っているのだ…
他にキーボードからの入力を受け取れて不具合の無い関数は無いかな?
初歩くさくてすまんが…

197:デフォルトの名無しさん
08/06/03 22:46:04
getcharとかそんなのなかったか?

198:デフォルトの名無しさん
08/06/03 22:49:32
動作が定義されている環境ならば
fflush(stdin)
でいいかな。

199:デフォルトの名無しさん
08/06/03 22:50:51
>>196
標準入力は全てfgets()で済む。

200:デフォルトの名無しさん
08/06/03 22:51:43
早速ありがとう。けど使い方がよくわからん

今ケータイだから使用例なんかを挙げて
もらえるとすごく助かるかも@新入社員、今帰り

明日午前中にコードレビューだから帰ったら今日中に
仕上げなきゃ…

201:デフォルトの名無しさん
08/06/03 22:54:30
printf("終了しますか?(Y/N)");
do {
c = getchar();
} while(c == 'y');


こんなんとかか?CUI系の関数使うの久々だから自信ない

202:デフォルトの名無しさん
08/06/03 23:04:51
>>200
ケータイだから使用例をってどういう流れだ?
conio.hのgetchとかもいいんでないの?

203:デフォルトの名無しさん
08/06/03 23:33:03
確定的にある入力を捕まえたいなら
プロンプトを表示する前にずべての文字を読み捨てておく
それが唯一の汎用な解

204:デフォルトの名無しさん
08/06/03 23:44:12
しかし、すべての文字を読み捨てたのかまだ文字が残ってるのかを知る術はない

205:デフォルトの名無しさん
08/06/03 23:50:46
バグが出るのはscanf()が悪いんじゃなくて使い方を理解してないのが悪い。
まあ、きちんとした使い方を理解させないで安易にscanf()で入力させる入門書や教師が一番悪いんだが。

206:デフォルトの名無しさん
08/06/03 23:59:22
仕事を持ち帰らせる会社が悪い。新入社員なら特に。

207:デフォルトの名無しさん
08/06/04 00:05:14
>>196だけど、様々ありがとう!
とりあえずgetcharを用いて行ってみるよ

文字として受けるから書式指定せずにいけるからね

これから実装だ…

208:デフォルトの名無しさん
08/06/04 00:12:37
fseek(stdin,0,SEEK_END) って未定義だっけ?

209:デフォルトの名無しさん
08/06/04 00:13:20
>>206
納期は明日の午前だからしょうがない
別に業務じゃないけど、納期に遅れる訳にはいかないことを
教えるためだと思う

210:デフォルトの名無しさん
08/06/04 00:13:53
wikipediaには改行コードまで読み飛ばすって方法が載ってるけど、scanf()が行単位で動作してないんだから、
そんなことしてたら、エラーのときと正常動作のときと動きがちがってくるとか面倒なことがありそう。

stdinをfflush()したりファイルポインタを先頭にもどすとかってフラッシュのやりかたがあるけど、移植性ないし
リダイレクトとかされたら、どう動くかわからんし。

fgets()とかで行単位で読み込んで、sscanf()を使うなり自力で解釈するのがシンプルで紛れのないやりかた。


211:デフォルトの名無しさん
08/06/04 00:23:35
>>209
業務では無いみたいだし、つか勝手に持って帰ってるだけだと思うけど
「納期に遅れる訳にはいかない」なら会社に泊まらせた方がまだいいなぁ

212:デフォルトの名無しさん
08/06/04 00:25:34
C言語で、リスト構造によるスタックとキューから要素数を取得する方法を教えてください(><)

213:デフォルトの名無しさん
08/06/04 00:27:34
要素数を別に記憶していないなら、先頭から始めて末尾まで順に辿ってその回数を数えるしかない


214:デフォルトの名無しさん
08/06/04 01:13:26
>>211
泊まり込みなんてほんとにあんのかなあ?
寝ないと逆に集中出来ないんじゃね?

215:デフォルトの名無しさん
08/06/04 01:16:47
3日ぐらい寝ずに仕事すれば覚醒する。

216:デフォルトの名無しさん
08/06/04 01:18:40
寝ないと集中できない は真
泊り込みなんてほんとにある も真

217:デフォルトの名無しさん
08/06/04 01:25:08
会社で寝ればすべて解決

218:デフォルトの名無しさん
08/06/04 01:57:58
>>217
移動時間が節約できるんだよね。
あとは思い立った瞬間に仕事ができるんだよね。
夜2時とかにひらめくこともある。

219:デフォルトの名無しさん
08/06/04 08:19:08
132のプログラムを118〜120のプログラムの中に入れたいんですけど、どこに入れたらいいですか?教えてください

220:デフォルトの名無しさん
08/06/04 08:35:54
>>219
1〜9の範囲の整数を入力してくれなかったら困るなあってところにいれる

221:デフォルトの名無しさん
08/06/04 19:35:54
>>218
無理をすると、あとでしっぺ返しがくる。
無理をしなければ納期に間に合わないようであれば、納期を延ばしてもらう。
これがいい。
そういう調整能力を身につけることも、プログラマーにとっては重要。

222:デフォルトの名無しさん
08/06/04 21:51:52
>>221
それがヒューマンスキルってやつ?違う?

223:デフォルトの名無しさん
08/06/04 21:54:28
何かの大賞とった川柳思い出した
無理をさせ 無理をするなと 無理を言い
だったけな?

224:デフォルトの名無しさん
08/06/04 22:17:30
ベーシックのスレは何処でつか?

225:デフォルトの名無しさん
08/06/04 22:18:08
(*p)++と*(p++)の違いがわかりません。

226:デフォルトの名無しさん
08/06/04 22:20:36
(*p)++は、
int n = *p;
n++;
*p = n;


*(p++)は、
int* p2 = p + 1;

くらいだと思っとけ

227:デフォルトの名無しさん
08/06/04 22:24:39
(*p)++;
は中身をインクリメント

*(p++) 及び *p++ は
はポインタをインクリメント

228:デフォルトの名無しさん
08/06/04 22:46:52
文字列の配列ってどうやって作るんですか?
char str[5]
str[1] ="文字列1"
str[2] ="文字列2"
str[3] ="文字列3"
printf(%s\n,str[1]);
とやってもエラーになるんですが。

229:デフォルトの名無しさん
08/06/04 22:48:06
それは文字列の配列じゃなくて
文字の配列だからね
どうしてもしたいなら二次元配列使う

230:デフォルトの名無しさん
08/06/04 22:49:41
str[][8] = { "文字列1", "文字列2", "文字列3" }

231:デフォルトの名無しさん
08/06/04 22:50:15
せめてこうだな
char* str[5]
まー、何がやりたい分からないから、これがベストとはとても言えないが

232:デフォルトの名無しさん
08/06/04 23:10:12
>>228
厳密な意味での文字列の配列とは、文字の二次元配列の各行要素に文字列が入っているものを言う。

char strlist[3][8];

このように宣言したとき、strlist[0] 〜 strlist[2] は、それぞれが char str[8]; と宣言した str と等価となる。

しかし、上記の配列では、全ての行要素の配列の大きさが同じである必要がある。
つまり、それぞれの行に入る文字列の長さが違っても、最も長いものに合わせなければならず、メモリを浪費しがちである。

それが嫌な場合には、主に文字列へのポインタの配列が使われる。

char *strlist[3];
char str0[5], str1[8], str2[4];
strlist[0]=str0;
strlist[1]=str1;
strlist[2]=str2;

見ての通り、strlist[0] 〜 strlist[2] は charへのポインタであり、それぞれが対応する配列の先頭を指している。
ということはそれぞれを文字列として扱うことができ、しかもそれぞれに対応する配列の大きさを個別に設定できる。

ただし、実際にはこのように静的な配列を行要素に使うことはほとんどない。通常、malloc() で割り付けた動的な領域を使う。
malloc() の扱いには熟練を要するので、安易に手を出すのは控えること。

それと念のために言っておくが、Cの配列の添字は 0 から始まる。char str[5]; と宣言したら各要素は str[0] 〜 str[4] である。

233:デフォルトの名無しさん
08/06/04 23:13:28
早い話、C言語に文字"列"型というものは存在しない

234:デフォルトの名無しさん
08/06/04 23:17:15
>>233
それを言ってもまったく早くはならないと思うが

235:デフォルトの名無しさん
08/06/04 23:40:55
早い話、文字列は使わないほうがいい

こうですか

236:デフォルトの名無しさん
08/06/04 23:58:14
文字列をしっかり理解してないのに文字列の配列に手を出すな

だろ

237:デフォルトの名無しさん
08/06/05 00:00:21
char str_array[N][]とchar *str_array[]じゃ、メモリ構成的にも全くの別物だしな

238:デフォルトの名無しさん
08/06/05 00:26:26
いきなり好奇心からCを勉強するのはおバカさん
Cの前にPASCALを勉強することはお利口さん
ただし、ハマるとオ××に転落さん
そこにさえ気をつければ、本当はPASCALから入って欲しいのだが
Cの勉強は、PACALを初歩をマスターしてからという奴
Free-PASCAL/Turbo-Delphi/ラザルス(だったけ)
みたいなフリーな処理系がネットで入手可能だし、条件は
恵まれているのだが...
なにせ、良いPASCALの入門書は絶版に近いのがイタい。
やっぱり××ムの影響だろな。

239:デフォルトの名無しさん
08/06/05 00:38:16
>>238
はいはいスレチスレチ

240:デフォルトの名無しさん
08/06/05 00:58:13
Cは初心者にはかなりハードルが高いプログラミング言語だよ

241:デフォルトの名無しさん
08/06/05 01:03:31
でもCから始めたよ

242:デフォルトの名無しさん
08/06/05 01:11:20
>>240
書き方次第だよ

判定式の中に計算とかそういうのをやらなければどうってことはない。

243:デフォルトの名無しさん
08/06/05 01:27:05
>>222
「約束を守る」という社会人の鉄則にすぎないのですが、なにか?

244:デフォルトの名無しさん
08/06/05 01:27:45
基本はわかった
スキルあげるため、どういう本がいい?

245:デフォルトの名無しさん
08/06/05 01:32:14
基本がわかったんなら自分で判断しろよw

246:デフォルトの名無しさん
08/06/05 01:35:42
ある程度の大きさの配列を宣言するとき、256とか1024とかキリのいい数字で割り当てた方がいいですか?

247:デフォルトの名無しさん
08/06/05 01:37:18
いや別に

248:デフォルトの名無しさん
08/06/05 01:38:47
>>238-242
以前こんなコードみた
int split_tsv(char ****split,char *filename);

【仕様】
タブ区切り文字列のみで構成されるテキストファイルを読み込み
を文字列配列の配列に変換。 char ***(ポインタ変数)をsplitに参照渡しする。
(sはNULL不可) 戻り値は、行数.

こういったコード、ちょっとやればすぐに出てくるけど、これって初心者向けか?
初心者には絶対に弄らせたくないコードだよな。

構造型プログラミング言語の黎明期の時代に、多くのプログラミング言語(特に
PASCAL)が型の概念を導入したんだが、実プロジェクトに投入したら中間型が乱造
されてしまい名前空間管理が極度に困難になって開発が大停滞してしまった。
このことの反省を十分に取り入れたのがCなんだが、
型の概念を徹底的に学んでない初心者がCで上のようなコーディングをしなければな
らないんだとあせるのは、危険きわまりない。とは家、中間型(作業型)の問題も実
にやっかい。
この世界は、やはり余り普通の人が入ってくる世界じゃないよ。

249:デフォルトの名無しさん
08/06/05 01:51:40
>>243
きめぇ

250:デフォルトの名無しさん
08/06/05 02:12:04
**** はさすがに気色悪い
自分ならそこまでやるなら多段の構造体に仕込んじゃうかも…つーかC++(略


251:デフォルトの名無しさん
08/06/05 02:19:31
char配列で表現した2進数を、頭から一文字ごとに比較したいのですが、
ソースAのような表記ではそもそも「error C2446: '==' : 'const char *' 型から 'int' 型への変換ができません。」が発生しコンパイルが通らず、
ソースBのような表記では、1文字ではなく、文字列全てを読んでしまって、if分岐に入ってくれません。
使用しているOSはWindowsXPHome, 使用しているコンパイラはVisual Studio 2005 Academic Editionです
どなたかご教授いただけないでしょうか

ソースA)
char tmp[8];
strcpy(&tmp[0], "11111000");
if (tmp[0] == "1")
{
...
}
if (tmp[1] == "1")
...
if (tmp[7] == "1")
{
...
}


252:デフォルトの名無しさん
08/06/05 02:20:02
ソースB)
char tmp[8];
strcpy(&tmp[0], "11111000");
if (strcmp(&tmp[0], "1") == 0)
{
...
}
if (strcmp(&tmp[1], "1") == 0)
...
if (strcmp(&tmp[7], "1") == 0)
{
...
}

253:デフォルトの名無しさん
08/06/05 02:23:15
'1'

254:デフォルトの名無しさん
08/06/05 02:27:21
>>253
if (strcmp(&tmp[0], '1') == 0)
{
...
}
とした場合は、下記のエラーが出てしまいます・・・
error C2664: 'strcmp' : 2 番目の引数を 'char' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照)


255:デフォルトの名無しさん
08/06/05 02:27:59
いや、
tmp[n] == '1' って事を言っているんだろう

256:デフォルトの名無しさん
08/06/05 02:31:01
なんでBのほうにとるw

257:デフォルトの名無しさん
08/06/05 02:33:55
>>255
おお、コンパイルも通り、動いてほしい動作もしてくれました!
ありがとうございました!

…よろしければなぜ通ったのか、っていうか"1"、'1'の違いは何なのか、お時間があればお教えくださいませんか

258:デフォルトの名無しさん
08/06/05 02:36:15
ああ、あつかましくて申し訳ないです。
入門サイトの、それについての解説が載っているページへのリンクや、
ググルキーワードでもお教えいただければ…

259:デフォルトの名無しさん
08/06/05 02:38:15
そんなのも知らないのにstrcpyとかは知ってるのか

260:デフォルトの名無しさん
08/06/05 02:40:05
"1" は { '1' , '\0' } の文字列、 n == "1" で比較してるのは(正確には違うんだろうけど)アドレス
'1' は 1バイトの文字コード(要するに数値)になる

まあ>>236

261:デフォルトの名無しさん
08/06/05 02:40:32
"1"だと文字列なので中身は
 1\0 (\0:ヌル文字)
となって先頭の1の部分のアドレスが入る

'1'だとそのままの文字が入る

あと8文字入れたいなら\0まで考えて
tmp[9]取っときなさい

262:デフォルトの名無しさん
08/06/05 02:43:59
>>259
恐縮です
独学の偏った順番で勉強しているからだと思います…

>>260
ありがとうございます!
文字列処理も場数ということで…
気を引き締めて使用していきたいと思います


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5147日前に更新/203 KB
担当:undef