C言語なら俺に聞け(入門篇) Part 26at TECH
C言語なら俺に聞け(入門篇) Part 26 - 暇つぶし2ch1:デフォルトの名無しさん
08/03/22 23:36:40
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 25
スレリンク(tech板)

教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 104代目
スレリンク(tech板)

2:デフォルトの名無しさん
08/03/22 23:37:35
Part 1 スレリンク(tech板)
Part 2 スレリンク(tech板)
Part 3 スレリンク(tech板)
Part 4 スレリンク(tech板)
Part 5 スレリンク(tech板)
Part 6 スレリンク(tech板)
Part 7 スレリンク(tech板)
Part 8 スレリンク(tech板)
Part 9 スレリンク(tech板)
Part 10 スレリンク(tech板)
Part 11 スレリンク(tech板)

3:デフォルトの名無しさん
08/03/22 23:39:08
Part 12 スレリンク(tech板)
Part 13 スレリンク(tech板)
Part 14 スレリンク(tech板)
Part 15 スレリンク(tech板)
Part 16 スレリンク(tech板)
Part 17 スレリンク(tech板)
Part 18 スレリンク(tech板)
Part 19 スレリンク(tech板)
Part 20 スレリンク(tech板)
Part 21 スレリンク(tech板)
Part 22 スレリンク(tech板)
Part 23 スレリンク(tech板)
Part 24 スレリンク(tech板)

4:デフォルトの名無しさん
08/03/23 00:07:16
過去スレ貼るのって、なんか意味あるの?

5:デフォルトの名無しさん
08/03/23 00:19:07
>>4さんがこの世に存在してるのと同じくらい意味があります!!

6:デフォルトの名無しさん
08/03/23 00:48:33
あんまり意味なさそうだな。

7:デフォルトの名無しさん
08/03/23 00:53:16
じゃ意味もなく貼ってるってことで。

8:デフォルトの名無しさん
08/03/23 01:37:06
過去スレ見たい奴が居るからそういう人向けにはあった方が便利
不要に思う奴はスルーすればいい

9:デフォルトの名無しさん
08/03/23 15:27:35
#include <stdio.h>

main () {
int player;
int i;
int r;

for(i = 0; i < 5; i++) {
r = scanf("%d", &player);
while (getchar() != '\n') {}
printf("%d 回目 ", i+1);
if(r) { printf("%d\n", player); }

else { printf("入力エラー\n"); }
}
return 0;
}


r = scanf("%d", &player);でrにはどのような値が入るのですか?
playerと全く同じ値が入るのでしょうか?
if(r)というのがどのような条件なのかもよくわからないです
よろしくお願いします

10:デフォルトの名無しさん
08/03/23 15:32:58
正しく入力を解析できた数、あるいは EOF が帰ってくる。

入力が無い場合は EOF が返される。
数値が入力されなかった場合は 0 が返される。
数値が入力されていていた場合は player にその数値が入れられ 1 が返される。

11:9
08/03/23 15:56:30
>>10
教えて頂いた事を元に調べ直したら理解出来ました
ありがとうございます

12:デフォルトの名無しさん
08/03/23 16:33:56
windows上でBCCを使っています。
1行ずつテキストファイルを読み込んで、条件により文字列の置換を
行うプログラムを作っているのですが、fgetsの基本的なところがわか
ってないもので上手く処理できずに困っています。

悩んでいる処理が

while(fgets(buf,512,fin)!= NULL){
....置換処理
fputs(buf,fout) //・・・処理しない行

という処理なのですが、出力結果をバイナリエディタで見ると改行"0D0A"
の前に"0D"が入ってしまいます。
fgetsでbufに読み込んだ終端に"0D"が挿入されるから当然の動作
なのでしょうが、それを上手く削除する方法がわかりません。
それで、しかたなく今は、

fseek(fout,-3,SEEK_CUR);
fprintf(fout,"\n");

なんてことをしています・・・(汗
いいやり方があれば教えて下さい。。。。

13:デフォルトの名無しさん
08/03/23 16:46:45
>>12
finをテキストモードでオープンすれば、改行は\nにならない?

14:デフォルトの名無しさん
08/03/23 16:51:05
char *p;
:
:
p = strstr(buf, "\r\n");
if (p != NULL) strcpy(p, "\n");



15:デフォルトの名無しさん
08/03/23 19:35:07
プロトタイプ宣言について教えて。
int myStrlen(const char* str) {
 return strlen(str);
}
って関数があったとき、
int myStrlen(const char* str);
これがプロトタイプ宣言だよね。
ANSI以前のプロトタイプ宣言が無いときは
int myStrlen();
こう書いていたんだっけ?
プロトタイプ宣言が無いときに、相互に呼び出される関数を
どう実現していたのかが気になった。


16:デフォルトの名無しさん
08/03/23 19:44:47
>>15
型チェックなしだから、空き放題に呼び出せたのでは?

17:デフォルトの名無しさん
08/03/23 19:46:15
現在 int myStrlen(); が int myStrlen(...); の時とほぼ同じような感じで使えるから、
それと同じような感じで使われてたんじゃないかな。

18:12
08/03/23 20:56:44
>>13さん
ありがとうございます!あっさり解決しました~

19:デフォルトの名無しさん
08/03/24 23:28:06
>>15
関数を呼び出す側が正しい引数を渡すものとしていた
引数について型変換が行われないのでキャストも必要だった

例として
sqrt(2);
の時
プロトタイプ宣言があれば 2 → 2.0 に変換して渡してくれるが
プロトタイプ宣言が無い場合 2 (整数)のままで渡されるので期待した返値が得られない

可変長引数関数は今でも型チェックができないので同じ問題がある
(標準関数についてだけは警告を出してくれるコンパイラもある)
printf("%f\n", 2);
printf("%f\n", 2.0);

20:デフォルトの名無しさん
08/03/25 01:30:20
色々とありがとう。
プロトタイプ宣言なしのコーディングなんて暫くしてなかったから、どんなものか忘れてた。
これで、新人とかに質問されてもちゃんと答えられるぜ。


21:デフォルトの名無しさん
08/03/25 19:56:30
ポインタのポインタについて困ってます。
メインから構造体のポインタを渡し、構造体に内容を追加して、
追加後のポインタを返してもらいたいのですがうまくいきません。
void add_line(int num,struct lines **current){
char input_line[512];struct lines *buffer_pre,*buffer_fow;int length,i; struct lines *p;
p=*current;
do{
gets(input_line);
if((*input_line != '.')&&(*(input_line+1) != '\0')){
buffer_pre=p;
//構造体の前後のポインタ取得の処理は省きました
//構造体とテキストの領域をMALLOCで確保します
if (buffer_pre == 0){       //リストの連結
p->next=0;
p->prev=0;
}else if((buffer_pre != 0)&&(buffer_fow == 0)){
p->next=0;
p->prev=buffer_pre;
buffer_pre->next=p;
else if((buffer_pre != 0)&&(buffer_fow != 0)){
p->next=buffer_fow;
p->prev=buffer_pre;
buffer_pre->next=p;
buffer_fow->prev=p;
};
};
}while((*input_line != '.')&&(*(input_line+1) != '\0'));
*current=p;
return;}
何がまずいのでしょうか?

22:デフォルトの名無しさん
08/03/25 20:06:25
教えて

char MyStrMid( char buff[], const char string[], int pos, int len )
{
 char *dest = buff;
 
 if ( pos < strlen(string) ){
  for ( string += pos ; len > 0 ; len-- ){
   if ( *string == '\0' ){
    break;
   }
   *dest++ = *string++;
  }
 }
 *dest = '\0';
 return( buff );
}

っていうプログラムを教えてGooで見つけました。
MIDができる関数なんだけど、
const char stringで宣言しているのに
*string++ しているので、stringの中身を変更しないで
この関数を使いたいんだけど、どうしたらいいんでしょう?

23:デフォルトの名無しさん
08/03/25 20:19:09
>>22
なぜ中身が変更されていると思ったのでしょう?

24:デフォルトの名無しさん
08/03/25 20:21:14
*dest++ = *string++;

*dest = *string;
dest++;
string++;
とほぼ同じ動作。
string の中身は変わらないっつーか、
変わってたら string は const だからエラー出る。

25:デフォルトの名無しさん
08/03/25 20:26:39
>>23,>>24
ありがとうございます。

>>23
なぜ中身が変更されているかは、*string++をしているからですよね

>>24
*string++で中身が変わってしまい、constでエラーが出ることは理解できるのですが、
応用として、変数を増やすことなく、この関数を使用できないでしょうか?

26:デフォルトの名無しさん
08/03/25 20:27:26
>>25
中身は変更されないので確認してねって事です

27:デフォルトの名無しさん
08/03/25 20:28:25
>>21
・ gets より fgets を使う。
・ input_line[0] == '\0' の時に最初の条件式ではマズい。
 そもそも意図通りの条件なのかも怪しい。
・ *(input_line+1) とか読みにくい。input_line[1] にしてくれ。
・ 省略するより、省略なしでアップローダーにうpしてくれ。
・ 同じ条件式を二度も書くのは無駄。
 無限ループにして if(! (条件)) { break; } した方がすっきりする。
・ 双方向リストはリングリストの形で実装すると、途中の if-else チェインが不要になる。
・ add_line は本当に1行追加の関数にして、
 add_input_lines っての作ってそこで add_line を逐次呼ぶ実装にした方がすっきりする。

変数の説明も無いし読みづらいしで
とりあえずすっきりさせてからということで。

28:デフォルトの名無しさん
08/03/25 20:29:24
>>25
>*string++で中身が変わってしまい、constでエラーが出ることは理解できるのですが、
だから変わらないっつーの。

29:デフォルトの名無しさん
08/03/25 20:29:31
>>21
ポインタを返してもらうならvoid *add_line()だろ。

30:デフォルトの名無しさん
08/03/25 20:54:59
>>26
中身は変わらないです。ごめんなさい。

>>28
「中身を変えようとして」エラーが出ているって認識で大丈夫ですかね?

すいません。もうちょっとがんばってみます。
ありがとう。

31:21
08/03/25 20:55:53
>>27
とりあえず、ソースをあげてみました。
URLリンク(www.uploda.org)
まだご指摘いただいた点直してない部分がありますが、一度見ていただけないでしょうか?
入力を終了する条件式は「.」のみが入力された場合です。
構造体の中身は
struct lines{
char *word;
struct lines *next;
struct lines *prev;
};
で、テキストエディタのようなものですので、リングにしてしまうと一行目が分からなくなるかなと?
と思っったのでリング型にはしませんでした。
変数は
char input_line[512];//文字を一時的に入れる配列
struct lines *buffer_pre,*buffer_fow;//挿入部分の前後のポインタを入れておくところ
int length,i;//文字列の長さを入れるlinegth、ループ様のi
struct lines *p;/mainから受け取った構造体のアドレスを保存するとところ
です。
>>29
えっと、名前の部分は戻り値ありの場合の指定ではないのですか??

32:デフォルトの名無しさん
08/03/25 21:20:17
>>31
>構造体に内容を追加して、追加後のポインタを返してもらいたい
と書いてあるけど違うの?内容を追加するだけならvoidのままでいいけど。

33:デフォルトの名無しさん
08/03/25 21:32:17
>>32
あ、もちろん構造体に中身を追加して、その追加した部分のポインタを返してもらいたいです。
それをポインタのポインタを渡して、それに追加した部分のポインタの内容を代入して返すようにしたいです。

mainに現在の構造体のポインタの位置を表すポインタ「now」有。
nowのアドレスをポインタのポインタたるcurrentに入れてadd_lineに渡す。
add_lineの中でcurrentにそこで関数内でつくった構造体のポインタPを代入する。

呼び出す時は何行目に行を追加するかを表すnumと構造体のポインタのポインタ二つを渡して
add_line(num,now);//nowはmain中の構造体のアドレス
のようにしようと思っていました。
now=add_line(num,now);という様に関数の戻り値を使う場合のみ型を指定するのではないのでしょうか?

34:デフォルトの名無しさん
08/03/25 21:45:52
[a][b][c][d][e] ってあった場合、num を 1 にした際には
<X> [a][b][c][d][e] ここに追加されて欲しいのか
[a] <X> [b][c][d][e] ここに追加されて欲しいのか
どっちなんだろう。

前者はこのリストの仕様だと面倒臭いよね。
特にリストの末尾に追加する際。

35:デフォルトの名無しさん
08/03/25 21:50:18
空のリストに追加する際は常にこの面倒くさい状態になるから・・・

36:21
08/03/25 22:24:05
>>34
学校の課題で、特定の行の後に追加する関数と、前に追加する関数が求められていて、
この関数は後に追加のほうなので、[a] <X> [b][c][d][e]に追加したいです。
もし0行目の後に追加(一番最初に追加)の場合は特定の行の前に文章を追加する関数に
移るようにします。
>>35
リングにしてしまうと最初の行が分からなくなってしまう気がします。
その場合は構造体の中に行番号を入れるしか思いつきませんでした。
ただX行からY行をZ行の後に移動などの処理の時に困る気がするのですが・・・

37:デフォルトの名無しさん
08/03/25 22:29:48
>>36
ダミーのノードを1つ用意する。

ダミーノードの次のノードが最初のノードで、
ダミーノードの前のノードが最後のノード。

最初のノードの前のノードがダミーノードで、
最後のノードの次のノードがダミーノード。

ダミーノードがあると、
「~の次に追加」 という関数にダミーノードを渡すと先頭に追加になり、
「~の前に追加」 という関数にダミーノードを渡すと末尾に追加になる。

そして、一切の NULL チェックが不要になる(assert くらいはした方がいいと思うけど)。

38:21
08/03/25 22:42:57
>>37
おぉ!なるほど!
確かに大量にあるNULLチェックが必要なくなります!
ダミーノードはmainのコマンドの入力→該当関数の動作というループが始まる前に
mainの中で用意しておけばいいんですよね?
その場合ダミーノードかどうかの判別は保持しておいたアドレスを使って
最初に戻るのなら
while(c = ダミーのアドレス){
    c=c->prev;};
とすれば出来ますよね?

あと、構造体のポインタへのポインタの使い方は

39:デフォルトの名無しさん
08/03/25 22:50:37
引数に直接返すより戻り値から返した方が
自由度が高くてよい。

40:21
08/03/25 23:07:17
>39
えと、X行からN行を入力テキストに置き換える、という関数の中で
X行とN行のアドレス、それを取り出すときに使ったX行からN行の
実際の行数のintを返す関数を用意したいと思っているのですが、
やはりそれは戻り値を一つに出来るよう更に小型化するしかないのでしょうか?

41:デフォルトの名無しさん
08/03/25 23:27:37
複数の値を返さないといけない場合は、
値を返す用の引数を別個に用意するのが普通かな。

今の add_line の仕様だと、
struct lines * 型の戻り値を current に渡す、とかできないっしょ。

まあとりあえず、
>>21 のポインタへのポインタの使い方自体は間違ってないので、
変なのだとしたら他の所がおかしいんだと思うよ。

42:21
08/03/25 23:38:34
>>41
色々教えていただいてありがとうございます!

とりあえず、
struct lines *add_line(int num,struct lines *current){
この様に戻り値を使って値を返すことにしました!

ただ、やはりポインタのポインタが疑問でして、
自分が書いたとおりであってるとすると、その前は
mainでポインタのポインタたる**pに*p=0、
構造体のアドレスはNULLということをしてるだけなのですが
この書き方がマズイのでしょうか?

あと、もう一つなのですが・・・値を返す用のの引数とは
関数の動作に必要な引数の他に、値をもらう用のポインタ変数を
用意するということでしょうか??

43:デフォルトの名無しさん
08/03/25 23:45:41
ああ、もうソースが消えてるわ。
main 側はまだ見てなかったわ。

main 側では struct lines *p; として
add_line(num, &p); という形にすることになるはず。

>あと、もう一つなのですが・・・値を返す用のの引数とは
>関数の動作に必要な引数の他に、値をもらう用のポインタ変数を
>用意するということでしょうか??
そうなる。

44:21
08/03/26 00:31:31
>>43
スイマセン、ソースは自動で消えてしまったみたいです・・・

main側では**pの様なものは宣言せずに、渡す時に&を使うのですね。

勉強になりました!ありがとうございました!

45:デフォルトの名無しさん
08/03/26 07:47:20
struct Lines; /* typedefのための前方宣言 */
typedef struct Lines Lines;
typedef Lines * LinesPtr;
struct Lines { char *word; LinesPtr next, prev; };
LinePtr linesGetLast(LinePtr p) { if(p){ while(p && p->next) p = p->next; } return p; }
LinePtr linesGetFirst(LinePtr p) { if(p){ while(p && p->prev) p = p->prev; } return p; }
LinesPtr add_line(int num, LinesPtr current)
{
char input_line[512];
LinesPtr temp_lines = NULL;
while(fgets(input_line, sizeof(input_line), stdin) != NULL){
if(input_line[0] == '.' || input_line[0] == '\0') break;
temp_lines = malloc(sizeof(Lines)); /* エラーチェック省略 */
temp_lines->prev = NULL; temp_lines->next = NULL;
temp_lines->word = malloc(sizeof(char) * strlen(input_line) + 1);
strcpy(temp_lines->word, input_line);
if(current != NULL){
temp_lines->next = current->next; current->next = temp_lines;
temp_lines->prev = current;
if(temp_lines->next != NULL) temp_lines->next->prev = temp_lines;
}
current = temp_lines;
}
return temp_lines; /* 割り込み終了位置を返す */
}

46:45
08/03/26 07:49:39
改行大杉長過ぎで二度怒られたわw >>45の続き、ってかコメント。

numの使い道が分からんかったのでやや違うかもしれんけど、
やりたいのは大体こんな感じ?(関数名はinsertとかの方が適切っぽい)
ソース見てないから断言できんけど、呼び出し元が渡すのはポインタでよさげ。
割り込み開始位置は呼び出し元の current->next を見る。
NULLで呼び出してる時は linesGetFirst(p) で。

ちなみに自分なら1つの独立した構造体を作る関数を別に作って
土台のリストと新しく作ったのを追加用関数に渡す形にするかな。
その方がどこに加えたいかの指定が楽になるし、
構造体に手を加えても作成用関数だけいじれば大体事足りるようになるので。

『ポインタのポインタ』はポインタをtypedefして独立した1つの型として見ると理解し易いかも。


47:デフォルトの名無しさん
08/03/26 15:22:26
>>22
気になったので書き直してみた (処理速度的には不利だけど)
char MyStrMid( char buff[], const char string[], int pos, int len )
{
for(;pos>0 && *string;pos--,string++);
sprintf(buff, "%.*s", len, string);
return buff;
}

48:デフォルトの名無しさん
08/03/26 18:58:32
~なら真を返すと、どういう意味かわかりません

49:デフォルトの名無しさん
08/03/26 19:38:27
0以外の値。
例えば常に真を返す関数tがあったとしたら、次のコードは常にtを出力する側へ分岐する。
if (t())
{
putchar('t');
}
else
{
putchar('f');
}

50:デフォルトの名無しさん
08/03/26 19:39:51
>>48
man コマンドとかマニュアル、ヘルプの読み方が分からないって事か?

51:デフォルトの名無しさん
08/03/26 21:35:01
真=はい
偽=いいえ

で覚えとけ

52:デフォルトの名無しさん
08/03/27 22:18:49
FIRフィルタをCで書くとどんなになりますかね?

53:デフォルトの名無しさん
08/03/27 22:22:24
>>52
for(i=0;i<srcsize;i++){
dest[i]=0;
for(j=0;j<fltsize && i+j<srcsize;j++){
dest[i]+=src[i+j]*flt[j];
}
}

54:デフォルトの名無しさん
08/03/27 22:30:18
>>52
コンボリューション演算をすればよろしい

55:デフォルトの名無しさん
08/03/27 22:39:26
>>52
// srcsize == fltsize == destsize (==2^x)
src_freq=fft(src, srcsize);
flt_freq=fft(flt, fltsize);
for(i=0;i<srcsize;i++) dest_freq[i]=src_freq[i]*flt_freq[i];
dest=fft(dest_freq, destsize);

56:デフォルトの名無しさん
08/03/27 22:42:53
入力した日は何曜日かを出したいのですが
どうしても曜日がずれて一日ずれて表示されてしまいます
どごが悪いのでしょう?
#include<stdio.h>

int main() {
int iyear,imonths,iday;
int sum,i;
int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
char*cweek[7] = {"日","月","火","水","木","金","土"};
sum =0;
printf ("input (e.g. ****/**/**)\n>>");
scanf ("%d/%d/%d",&iyear,&imonths,&iday);
/*閏年の判定*/
for(i=1;i<year;i++){
if((year%4==0)&&((year%100!=0))||(year%400==0)){
sum++;
i++;
}
year--;
/*前月までの日数*/
for (i =0; i < imonths-1; i++) {
sum += m_array[i];
}
year++;
sum=sum+day;
//曜日の出力
printf("%s曜日",cweek[sum%7]);
return 0;
}
}


57:デフォルトの名無しさん
08/03/27 22:48:13
>>56
それではコンパイルすらできませんが

58:デフォルトの名無しさん
08/03/27 23:45:44
読んでないけど演算結果が0==月曜日とかってことないよね?

59:デフォルトの名無しさん
08/03/27 23:50:23
ヒント:グレゴリオ暦で遡って行った場合、西暦1年1月1日は月曜日

60:デフォルトの名無しさん
08/03/28 00:45:01
>>57
#include<stdio.h>
int main() {
int year,months,day;
int sum,i;
int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
char*cweek[7] = {"日","月","火","水","木","金","土"};
sum =0;
printf ("input (e.g. ****/**/**)\n>>");
scanf ("%d/%d/%d",&year,&months,&day);

/*閏年の判定*/
for(i=1;i<year;i++){
if((year%4==0)&&((year%100!=0))||(year%400==0)){
sum++;
i++;
}
year--;

/*前月までの日数*/
for (i =0; i < months-1; i++) {
sum += m_array[i];
}

year++;

sum=sum+day;
//曜日の出力
printf("%s曜日",cweek[sum%7]);
return 0;
}
}

61:デフォルトの名無しさん
08/03/28 00:52:32
>>60
あなたが手を加える前のプログラムに戻してみては?

62:デフォルトの名無しさん
08/03/28 01:08:24
>>61
それだとできないことはないんですけど
別で作ってみたいなと思いまして・・・・

63:デフォルトの名無しさん
08/03/28 01:11:37
>>62
まずはインデントをしっかりそろえてみ?
forがおかしなネストをしててループ変数iが破壊されてるぞ

64:デフォルトの名無しさん
08/03/28 01:23:55
ファイルを読み込んで、構造体に入れて、それを表示させたいのですが何故か上手くいきません。
どこを直したらいいのでしょうか?
struct lines{
char *word;
struct lines *next;
struct lines *prev;
};
void main(){
char input_line[512],file_name[100];
struct lines *buffer_pre,*buffer_fow;
int length,i;
struct lines *p;
FILE *fp;
printf("*");
gets(file_name);


65:デフォルトの名無しさん
08/03/28 01:24:48
if((FILE *)NULL==(fp=fopen(file_name,"r"))){
printf("can not open\n");
};
i=0;
while(i=0){
fgets(input_line,513,fp);
  if(feof(fp)){
break;
    };
  if(ferror(fp)){
break;
};
//前後のポインタの取得
buffer_pre=p;
if (buffer_pre == 0){
buffer_fow=0;
}else{
buffer_fow=0;
}
//領域の確保
p=(struct lines *)malloc(sizeof(struct lines));
length=strlen(input_line);
p->word=(char*)malloc(length+1);
strcpy(p->word,input_line);



66:デフォルトの名無しさん
08/03/28 01:25:19
//リストの連結
if (buffer_pre == 0){
p->next=0;
p->prev=0;
}else if((buffer_pre != 0)&&(buffer_fow == 0)){
p->next=0;
p->prev=buffer_pre;
buffer_pre->next=p;
};
};
fclose(fp);
       while(p->prev != 0){
p=p->prev;
};
while(p != 0){
printf("%s\n",p->word);
p=p->next;
};
return;}

67:デフォルトの名無しさん
08/03/28 01:59:43
何がどうなってどう上手くいかないのかくらい書いてくれ。
>fgets(input_line,513,fp);
なんで513なんだ?

68:デフォルトの名無しさん
08/03/28 02:02:39
>while(i=0){
代入でいいのか?

>};
関係ないけど、なんですべてのスコープの後ろにセミコロンが?

なんか他にもつっこみたくなる要素が満載だぞw

69:64
08/03/28 02:19:59
>>68
すいません、そこは「==」でした・・・
あとスコープの外側にはセミコロンはいらないんですね・・・

>>67
説明が足りなくて申し訳ございません・・・。

まず513ですが、一行の行数の最大値が512なので、NULL文字の分も入れて513にしてみました

問題点なのですが、「//リストの連結」という部分のすぐ下で読み込んだ構造体をつないでいきます。
その段階では構造体の現在のアドレスと現在の構造体の->prevのアドレスは正しく表示されるのですが、
ループを抜けた後、構造体のアドレスを一番最初に戻すために、       
while(p->prev != 0){
p=p->prev;
}
を実行しています。その途中でprevのアドレスがずれて、セグメント例外になってしまいます。


70:デフォルトの名無しさん
08/03/28 04:18:05
>buffer_pre=p;

71:デフォルトの名無しさん
08/03/28 04:21:55
>>69
ならinput_line[512]も513にしたら?

72:64
08/03/28 07:31:11
>>71
あ、確かに。ありがとうございます。

>>70
pは関数が始まる時に0に初期化していて、
一列終わるごとにそのその構造体のアドレスがbufferf_preに
入るので間違っては居ない気がするのですが・・・


73:デフォルトの名無しさん
08/03/28 07:40:31
>>63
見直してみましたがよくわかりません
どこのfor文なのでしょうか?


74:デフォルトの名無しさん
08/03/28 07:44:24
>>72
>70

75:デフォルトの名無しさん
08/03/28 07:46:28
>>73
あんたの節穴で見直すのではなく、インデントを揃えてみろ。
できればエディタで。

76:デフォルトの名無しさん
08/03/28 07:48:08
>>73
/*閏年の判定*/
for(i = 1; i < year; i++){

/*前月までの日数*/
for (i =0; i < months-1; i++) {

どっちもi使ってるだろ?後者で上書きされてるだろう?


77:デフォルトの名無しさん
08/03/28 10:01:09
>>72
>70で問題点が理解できないようじゃ、プログラムに向いてないだろ。
無意味で無駄な部分多すぎるし。

78:デフォルトの名無しさん
08/03/28 14:01:52
p == NULLで初期化してwhile(i==0)にしたら動いたけど

79:デフォルトの名無しさん
08/03/28 20:20:18
>>72,73
『間違っては居ない気がする』とかいってないで
デバッガでブレークポイント置いてステップ実行するなり
assert()とかprintf()とか入れて変数の状態を確認しようよ
見直すって眺めるのと違うんだけど

80:デフォルトの名無しさん
08/03/28 22:44:23
#include <stdio.h>
void main()
{
int count;

for (count = 0; count < 5; count++) {
printf( "countは今%dです\n", count );
}
if(count==4){printf("正解です%dです\n",count);}
else{printf("残念");}

}

VC++2008でデバックしましたがなぜかこれが"残念"のほうが出力されます。
countは4だと思うんですがなにか間違えてますか?

81:デフォルトの名無しさん
08/03/28 22:45:30
>>80
count の値を表示してみればいい

82:デフォルトの名無しさん
08/03/28 22:54:43
>>81
forで5のprintfが実行されなくてもカウントは5になってるんですね
ありがとうございました

83:デフォルトの名無しさん
08/03/28 23:06:04
count++のあとcount < 5を判断する

84:デフォルトの名無しさん
08/03/28 23:18:13
>>82
つーか、5になったからループを抜けたんだよ。

85:デフォルトの名無しさん
08/03/29 11:28:37
#include<stdio.h>
main(){
char a[80],b[32];
int ca(char *,char [],int *),i,n;
while(1){
printf("文字\n");
scanf("%s",a);
n=0;
ca(a,b,&n);
for(i=0;i<n;i++){
printf("%c ",b[i]);
}
printf("\n\n");
}
}
int ca(char *s,char t[],int *n){

int i;
while(*s){
for(i=0;i<*n;i++) if(*s==t[i]) break;
if(i>=*n){
t[i]=*s;
(*n)++;
}
s++;
}
}

nがどのようになっているのか理解不能です。
*n と nがどうなっているのか教えてください。

86:デフォルトの名無しさん
08/03/29 11:46:37
どこが分からないのか言ってくれないとどうしようもない

1行ずつ追っていって、結果を紙に書いていくんだ
そうすればどこの行が分からないのかが分かる


87:デフォルトの名無しさん
08/03/29 11:48:09
*nとn[0]が同じだってことは判っているのだろうか。

88:85
08/03/29 11:55:52
8行目でn=0となっていて、20行目の*nの値はどうなるのでしょうか?


89:デフォルトの名無しさん
08/03/29 11:58:13
最初は0だよもちろん。

90:デフォルトの名無しさん
08/03/29 11:59:10
>>88
1になったらそれ以降増えない
whileにprint分入れて*nを出力したりとかして自力で知らべられるようにした方がいいよ

デバッガというものもあるし

91:デフォルトの名無しさん
08/03/29 12:01:51
増えるだろw
aに入った文字列を一文字づつ取り出してbに格納、
既出の文字は無視、格納した文字の総数をnに入れてく関数だよ。

92:デフォルトの名無しさん
08/03/29 12:06:21
>>91
馬鹿?

93:85
08/03/29 12:11:59
ごめんなさい。理解できないみたいです。
まずfor(i=0;i<*n;i++)の*nは最初は0なんですよね?
だと繰り返さないような気がしてなりません。

94:デフォルトの名無しさん
08/03/29 12:13:29
バカは>>90だろw

95:デフォルトの名無しさん
08/03/29 12:14:47
>>93
そうです繰り返しません
そして次のif文はi が0 , *nが0なので真となり中身が実行されますが
その結果*n が1となりwhile(*s)の次の回では実行されません
そのままなにもしないままwhile文が回り続けて終了です

96:デフォルトの名無しさん
08/03/29 12:16:18
>>90=95?
でたらめ書く前に実行してみたら?

97:デフォルトの名無しさん
08/03/29 12:19:18
>>96
お前がやれよアホ

98:デフォルトの名無しさん
08/03/29 12:30:41
a[]は入力した文字列、b[]はその文字列から重複した文字を抜いた文字列、
nはb[]の文字数になる。

99:85
08/03/29 12:36:35
aaaと入力したときを考えると
for文はi=0,*n=0だから繰り返さないで次のif文にいき
実行されてt[0]にaが代入され、*nの中身がプラス1されて*n=1となって、2番目のaに移る。

for文はi=0,*n=1だから一回繰り返されてif文で*s=t[0]ならbreakで打ち切りされて
次のif文でi=0,*n=1だからだめで3番目のaに移る。

見たいな感じでいいんですか?

100:デフォルトの名無しさん
08/03/29 12:41:02
そうだね。

101:85
08/03/29 12:43:11
すみません。ちょっとだけ理解できたようです。
みなさんありがとうございます。

102:デフォルトの名無しさん
08/03/29 12:43:54
要するに、
forは文字(*s)がtの中で既出かどうか探している。
次のifは、既出でない場合に条件が成立し、
tに文字(*s)を追加。
*nはtに格納した文字数だよ。

103:デフォルトの名無しさん
08/03/29 12:46:57
春になると90みたいなキチガイが湧くんだなw

104:デフォルトの名無しさん
08/03/29 12:49:40
>>102
nは文字数なんですね。
あとnは*nとする必要もないですよね?

105:デフォルトの名無しさん
08/03/29 12:51:20
main関数内のnとca関数内の*nは別物。
できれば違う変数名にした方が混同しなくていいと思うけど。

106:デフォルトの名無しさん
08/03/29 12:58:19
>>105
main関数内のfor文のnはca関数内の*nの値が入るのですよね。

107:デフォルトの名無しさん
08/03/29 12:58:45
>>104
>あとnは*nとする必要もないですよね?
必要ないと思うならそう書き換えてコンパイルしてごらん。

108:デフォルトの名無しさん
08/03/29 12:59:41
yes

109:デフォルトの名無しさん
08/03/29 13:05:09
>>107
文字がでなくなった。
なんかもう頭がこんがらがってきた。
ポインタって難しいんですね・

110:デフォルトの名無しさん
08/03/29 13:15:01
>>109
難しいといわれてるが一度理解するとそうでもなく、
プログラミングする上でこの上なく便利な機能だ。
めげずに落ち着いて頑張るといいよ

111:デフォルトの名無しさん
08/03/29 13:19:28
プログラム書くときはなんか本とか見ながら書いてますか?

112:デフォルトの名無しさん
08/03/29 13:19:39
この場合型が違うのに変数名を同じnにしてるのが混乱のもとじゃね?

113:デフォルトの名無しさん
08/03/29 13:22:01
>>109
caの中のnは、mainの中のnを指して(ポイントして)いる。
caの中の*nという表記は、mainの中のnを読んだり書き換えたりしている。

114:デフォルトの名無しさん
08/03/29 13:22:53
無理に引数で渡さなくても
int ca(char *s, char t[])
{
int i, n = 0;
while(*s) {
for(i=0; i<n; i++) if(*s==t[i]) break;
if(i==n) {
t[i] = *s;
n++;
}
s++;
}
return n;
}
にしてmain内でn = ca(a, b)ってすればまだ分かりやすいのに。

115:デフォルトの名無しさん
08/03/29 13:31:58
>>111
日本語書くときはなんか辞書とか見ながら書いてますか?
という質問と同じに聞こえる。

116:デフォルトの名無しさん
08/03/29 13:56:40
>>113
なるほど、わかりました。
なんとなくですが>>

>>114
たしかにそのほうがわかりやすそうです。

117:デフォルトの名無しさん
08/03/29 15:08:02
>>115
言い得て妙 だな

118:デフォルトの名無しさん
08/03/29 15:19:06
2chの書き込みくらいでは辞書なんて引きません。
でも、ちょっとまじめな文章を書くときには、国語辞典を引きます。

119:デフォルトの名無しさん
08/03/29 15:35:24
日本語に例えるのは上手くないような・・
英語だとしっくりくる

120:デフォルトの名無しさん
08/03/29 17:17:22
正解はこれな
日本語しかわからないあなたがフランス語を書くときに辞書無しで書けますか?

121:デフォルトの名無しさん
08/03/29 19:29:42
>>111
時々リファレンスみる程度。初心者でなければコピペとかないから。
そう意味できいてるなら真面目に勉強してください。

122:デフォルトの名無しさん
08/03/29 22:47:33
ポインタについて質問です
整数型とint ポイント型の違いがわかりづらいのですが
ポイント型はアドレスを格納できて整数型はアドレスを出力するだけですか?

123:デフォルトの名無しさん
08/03/29 22:57:35
>>118
そんなもんだろ。だいたいは頭に入ってるから空で書ける。
細かい仕様(引数の順番とか関数の戻り値とか)が必要になったらネットなり書籍なりで確認して書く。

124:デフォルトの名無しさん
08/03/29 23:09:18
>>122
変数からアドレスを求めるのはアドレス演算子&。
整数型はアドレスを出力するだけというのはなんか変だ。


125:デフォルトの名無しさん
08/03/29 23:09:35
>>122
int*はint型の変数のアドレスを格納する変数

int x=50;
int *xp = &x;

この時、printf("%d",*xp) と printf("%d",x) は50を表示し、
printf("%p",xp) と printf("%p",&x) はxのアドレスを表示する

126:デフォルトの名無しさん
08/03/29 23:46:54
>>124
アドレスを変数に格納せず&で出力ができるという感じですか?
>>125
printf("%d",*xp)が50を表示するというのが難しく感じるところです
*xpという箱は整数型で宣言されそこには&xというアドレスが代入される
となるとprintf("%d",*xp)ではアドレスが出力されると考えてしまいます。

127:デフォルトの名無しさん
08/03/29 23:50:00
変数はあくまでxp

128:デフォルトの名無しさん
08/03/29 23:59:29
なんとなくわかりました
*xpはアドレスを格納する変数
だからprintf("%d",xp)だとそのままアドレスを出力
printf("%d",*xp)はわざわざ*をつけてるから逆にデータのほうを表示する

129:デフォルトの名無しさん
08/03/30 00:26:12
2行目の「*xp」は「xp」ね。それ以外は大体その認識でOK

130:デフォルトの名無しさん
08/03/30 09:26:32
そうかな、なんか危ういきがす

131:デフォルトの名無しさん
08/03/30 10:37:35
int *xp = &x;
これと
printf("%d", *xp);
これの「*」の意味が違うことに>>128は多分気付いていない。
同じ文字を逆の意味の2つの演算子に使うという、C言語の糞仕様のおかげだな。
「ポインタ宣言子」と「間接参照演算子」の違いね。

そもそも初心者に教えるときに、
int *xp = &x;
では混乱が起きる。

int *xp;
xp = &x;
上のように書いてやらないと
int *xp = &x;
  ↑
意味的にはここで切れていることに、初心者は気がつかない。

132:デフォルトの名無しさん
08/03/30 11:40:43
>>131
「int* xp」と書いた方がわかりやすいかな。
「int*」が変数の型(intへのポインタ型)、xpが変数名。

133:デフォルトの名無しさん
08/03/30 11:56:25
int* xp, x

134:デフォルトの名無しさん
08/03/30 12:05:48
>>133
C言語のダメなところだよね。「int *」が型なのに、宣言は個別に「*」を付けなきゃいけないなんて。
複数の変数を1行で宣言できることがそんなに重要なんだろうか。

135:デフォルトの名無しさん
08/03/30 12:17:50
int i, *p, (*f)();

136:122
08/03/30 15:44:32
printf("%d",*xp)というのは間接参照演算子というポインタ変数の機能なんですね
まだそれは勉強してませんでしたがおかげでわかりました

ポインタの練習用プログラムを見てどう出力されるかはわかるようになってきました
ありがとうございました

137:デフォルトの名無しさん
08/03/30 19:28:11
typedef struct
{
int Number;
}DATA , *PDATA;
int main()
{
DATA data;
PDATA pdata;
data.Number = 10;
pdata = &data;
printf("%d",pdata->Numer
}
*PDATAはポインタ型を作っているという解釈でよろしいんでしょうか?
ちなみに
typedef char *PCHAR;を書くと
sizeof(char) == 1
sizeof(PCHAR) == 4
になってました。


138:デフォルトの名無しさん
08/03/30 19:38:53
>>137
そのとおり。
DATA*とPDATAが同じ。
char*とPCHARが同じ。

139:137
08/03/30 20:06:28
>>138
ありがとうございます。

140:デフォルトの名無しさん
08/03/31 04:46:11
戻り値の最上位ビットが 1 のときはAを、0 のときはBを示す関数、REABがあるのですが、
if(REAB() < 0) //Aの時
となるのは何故なんですか?

141:デフォルトの名無しさん
08/03/31 04:48:39
2の補数の場合はそうなる
あとはぐぐればすぐ分かる

142:デフォルトの名無しさん
08/03/31 04:53:28
最上位ビットが1なら負の数になるんですね
ありがとうございました

143:デフォルトの名無しさん
08/03/31 12:22:07
>>142
Cの規格上は必ずしもそうなると言う保証はない点に注意。
そもそも、「最上位ビット」に意味があるのだからきちんと最上位ビットをチェックするロジックを書くべき。
# 処理速度などを睨んで改変するのは二の次三の次。

144:デフォルトの名無しさん
08/03/31 19:31:48
>>143
符号つきで最上位ビットが 1 の場合は負ってのは規格で保証されてなかったっけ?
その制限の中でどういう負数表現をとるかは環境依存だけど。

145:デフォルトの名無しさん
08/04/01 02:35:47
>>144
REAB()の戻り値がsignedなんて、どこにも書かれていませんよ。


146:デフォルトの名無しさん
08/04/01 03:03:58
例えば極端な話、戻り値がcharだったらコンパイルオプションでsignedかunsignedか切り換えられるかも知れない。
だとすると、signedのときは正しく動いてunsignedのときは(エラーも起こさず)正しく動かないことになる。
>143ではないが、先ずはそれに頼らないコードを書いた方がいいとは思う。

147:デフォルトの名無しさん
08/04/01 07:32:19
やらない方がいい事は確かだけど、
結局規格ではどうなってるんだ?

148:デフォルトの名無しさん
08/04/01 08:40:35
>>144
規格で決まってるのは、符号ビットが1ビットあることだけじゃなかったっけ?

149:デフォルトの名無しさん
08/04/01 12:29:56
FIRフィルタのプログラムで浮動小数点演算を使わずに実装
したいのですが、普通係数hnは浮動小数点ですよね。
入力のadは24ビットで係数hnを32768倍して固定小数点にして
最後に32768で割ろうとしたのですが、hn[k] * xn[k]の部分で
オーバーフローの可能性がでてきます。
回避するよいやり方はないでしょうか?

#define ORDER_2 50
static double xn[ORDER+1];
long firFilter(long ad)
{
long yn, acc;
int k;

xn[0] = ad;

acc = 0.0;
for (k = 0; k <= ORDER; k++) /* multiply and accumulate */
acc = acc + hn[k] * xn[k];
yn = acc;
for (k = ORDER; k > 0; k--) /* shift input samples */
xn[k] = xn[k-1];
return yn; /* output */
}

150:デフォルトの名無しさん
08/04/01 12:34:30
>>149
コンパイラによるけど long long を使うとかは?

151:デフォルトの名無しさん
08/04/01 12:55:46
・32768倍をやめて1024倍とか256倍とかで妥協する
・long long intを使う
・素直にfloatを使う

例えばx86でSSE2が使えるなら、巧く書けばベクタ化できるから下手すりゃ整数で小細工するより速いよ。

152:デフォルトの名無しさん
08/04/01 13:53:13
dest.txtの内容
[abcdefgabcdefg]
HANDLE hFile;
BOOL bVal;
DWORD numOFRead;

hFile = CreateFile("dest.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
DWORD dwSize = GetFileSize(hFile,NULL);
char *file_buffer = (char *)calloc(dwSize+1,sizeof(char));
if(file_buffer == NULL){
return -1;
}

bVal = ReadFile(hFile,file_buffer,dwSize,&numOFRead,0);
if(bVal == 0){
return -1;
}
CloseHandle(hFile);
dest.txtの中のfgという文字列をajkoに置き換えてファイル生成したいんですが、
どうすれば出来ますか?

153:デフォルトの名無しさん
08/04/01 14:25:42
system("sed -e 's/fg/ajko/g' dest.txt > foo")

154:デフォルトの名無しさん
08/04/01 14:40:13
apple
test
hello

と言うテキストを
String[ ][ ]

の様な2次元配列で読み込みたい場合、
Stringの確保はどのようにすればよいのでしょうか?

155:デフォルトの名無しさん
08/04/01 14:57:03
Stringって何よ?
ここはCのスレだけど、C++かC#かJavaか何かと間違ってやしませんか?

156:デフォルトの名無しさん
08/04/01 15:13:53
char String[][]の積もりだろ。

>>154
文字列長に制限があってよければ、例えば
char String[][10] = {"apple", "test", "hello", };

可変長にしたいとか、そもそも文字列も可変個数だと言うのなら、ポインタのポインタを使うことになる。
まぁ、入門サイトでも探してくれ。それで判らなければ出直してくれて構わんから。

157:デフォルトの名無しさん
08/04/01 15:23:36
>>155
済みませんでした。

>>156
ありがとうございました。

158:デフォルトの名無しさん
08/04/01 15:45:25
>>153
それは何ですか?

159:デフォルトの名無しさん
08/04/01 19:53:37
>>153について誰か教えて下さい。

160:デフォルトの名無しさん
08/04/01 20:12:44
Stringは型の名前にあるからねえ
俺は文字列変数名にstrやsを使う

>>159
sedプログラムに3つの引数-eと's/fg/ajko/g'とdest.txt を渡して呼び出す
sedプログラムが標準出力したメッセージはfooというファイルに書き込む
かな?
sedの質問があれば正規表現スレでどうぞ

161:デフォルトの名無しさん
08/04/01 20:45:25
すみません。
私Windowsです。

162:デフォルトの名無しさん
08/04/01 21:00:44
私はIRIXです

163:デフォルトの名無しさん
08/04/01 21:12:58
Windows でも Cygwin とかある

164:デフォルトの名無しさん
08/04/01 21:15:01
これを愛用している
URLリンク(www.vector.co.jp)

スレチだが

165:デフォルトの名無しさん
08/04/02 18:36:45
曖昧な質問で悪いのですが、

picをはんだして、モーターとリモコンに繋げなければなりません。

そういった用途のc言語プログラムというのはどこで拾えばよいのでしょうか?

166:デフォルトの名無しさん
08/04/02 19:40:13
宿題なら先生、仕事なら先輩。

167:デフォルトの名無しさん
08/04/02 20:52:03
>165
自分の文章を読み直してみろ
その文章で何を言ってるか理解できるか?



168:デフォルトの名無しさん
08/04/02 20:55:38
>>167
きっとロボット制御して半田付けするってことだ
で、ロボット制御するためのc言語プログラムというのを探している


169:デフォルトの名無しさん
08/04/02 20:57:00
>>165
導線と半田を用意して、こてで溶着すればいいんじゃない?

170:デフォルトの名無しさん
08/04/02 21:05:38
位置独立コードの事かと思ったよ。

171:デフォルトの名無しさん
08/04/02 23:09:20
Cである一定のstate数ループさせる方法ってあるんけ?


172:デフォルトの名無しさん
08/04/03 00:20:25
state数って何よ、asm("NOP") * nってこと?

173:fxで裁判中。教えて
08/04/03 08:28:12
外国為替証拠金取引会社のアトランティックトレードと裁判になりました。

裁判の内容をここに記してみました
システム障害等でくわしいかた、是非とも情報をお待ちしております。よろしくお願いします。
URLリンク(members3.jcom.home.ne.jp)


174:デフォルトの名無しさん
08/04/03 10:49:25
なかなかの魚拓が取れたみたいなので、ここに置いておきますね。
ZDNet Japan builder「C/C++のポインタの機能--参照渡しののような処理」
URLリンク(s03.megalodon.jp)

オリジナルは
URLリンク(builder.japan.zdnet.com)


175:デフォルトの名無しさん
08/04/03 11:20:59
すげえバカだw
そういやこの筆者と似たようなことぬかしてたヤツが宿題スレでボコボコにされてたな。

176:デフォルトの名無しさん
08/04/03 15:25:56
あちこち同じリンク張るな。いい加減うっとおしい。

177:デフォルトの名無しさん
08/04/03 17:55:05
全く無知な人間が
C言語をマスターするにはどれくらいの時間がかかりますか?

178:デフォルトの名無しさん
08/04/03 17:58:15
>>177
物覚えの良い人ならそれだけ早いだろうし
やる気によっても左右される
マスターがどれくらいの事を言ってるのかもわからない

179:デフォルトの名無しさん
08/04/03 18:10:47
僕もマスターしたという基準がよく分からないのですが
C言語の試験とか資格ってのはあるんですか?

180:デフォルトの名無しさん
08/04/03 18:19:43
聞いたことないし、あったとしても役立たないものであることは確かだな。
著名なプログラマが資格を持っているなんて話、聞いたことがない。

181:デフォルトの名無しさん
08/04/03 20:58:04
最低限の足切くらいはできるんじゃないか?
Fizz-Buzz みたいにw

使えないやつが暗記してくるのは見破れないけど
暗記すらできないやつなら落とすことができる
使えるやつは暗記する必要もない、と

182:デフォルトの名無しさん
08/04/03 21:02:56
そのレベルのcの資格なら存在しているな

183:デフォルトの名無しさん
08/04/03 22:36:16
>>177
参考書と問題集何冊か買って受験勉強並みに真剣に勉強すれば3ヶ月くらいで
1000行程度のフリーソフトが作れるくらいにはなる。マスターとは程遠いけどね…


184:デフォルトの名無しさん
08/04/03 23:50:20
うちは1プロジェクト数万行レベルの組み込みCなんだが、全く無知の人間がきたとして
作業要員に換算できるレベルに1~3か月ってとこかな?
PCに慣れているかどうかでかなり変わるとは思うが。

185:デフォルトの名無しさん
08/04/04 17:44:31
コンパイラの使い方がわかりません。
例えばtest.cppをVC++でコンパイルするとして
cl.exe D:/test.cpp
と実行してもコンパイルは出来るのですが、
どこにプログラムが作られているのかわかりません。
プログラムの保存先はどのように指定すればよいのでしょうか?

186:デフォルトの名無しさん
08/04/04 17:55:02
cl.exe /help
と実行すれば、指定できるオプションの一覧が出る

187:デフォルトの名無しさん
08/04/04 19:21:06
>>185
カレントディレクトリに実行ファイルができているんじゃないかな。


188:デフォルトの名無しさん
08/04/04 22:45:35
#include <stdio.h>
int main(void)
{
char str[2];
scanf("%s",str);
printf("%c %c\n",str[0],str[1]);
return 0;
}

これをVC++で実行しました。
EOSを考慮して01という2桁の入力をすると結果は0 1と正常な結果なんですが
なぜかデバックエラーがでてしまいます。
なにが問題なんでしょうか

189:デフォルトの名無しさん
08/04/04 22:48:49
char str[3];

190:デフォルトの名無しさん
08/04/04 22:49:34
>>188
\0 が入る余地がない

191:188
08/04/04 22:57:33
0から始まるから[0]と[1]に文字が入って[2]に\0が入るんじゃないんですか?

192:デフォルトの名無しさん
08/04/04 22:59:12
char str[2];
これだと二文字分の領域しか確保した事にならない

[0] = '0';
[1] = '1';
[2] = '\0';

の3Byte必要

193:デフォルトの名無しさん
08/04/04 23:00:24
>>191
str[2]を使うなら、char str[3];で定義しないとダメ。

194:デフォルトの名無しさん
08/04/04 23:03:32
添え字が0から始まる事と、配列の要素数は別

char str[0];

と書いても1文字分確保されるわけじゃない

195:188
08/04/04 23:13:06
今char str[0];で宣言してみたらサイズが0の宣言は無効とでました。
なるほど、てことはchar str[1];だと1文字が入るサイズってなわけですね。
皆さまありがとうございました。

196:デフォルトの名無しさん
08/04/04 23:32:33
>.188
慣れてしまえば、なんでもないことなんだが。
Cの初心者が最初につまずく問題であることは確か。

1.文字列を格納する文字配列は、文字列の最後の\0分も含めて確保しなければならない。
2.配列を定義するときの添え字(char str[3]の3)は、配列要素の数であり、どこまで使うかではない。

197:デフォルトの名無しさん
08/04/04 23:34:24
追加
3.Cの配列の添え字は0オリジンである。

198:デフォルトの名無しさん
08/04/05 00:13:30
すみませんCの質問とは若干異なるかもしれませんが
「JmEditor2」を使用していて下パネルで
『cファイルをコンパイルして作ったexe』を実行したときに
[scanf]などの入力を必要とする操作部分が実行できません
解決策を知っている方がいればお願いします

コマンドプロンプトから同じexeファイルを実行したところ問題なく動きました

199:デフォルトの名無しさん
08/04/05 00:32:38
JmEditor2のヘルプには入力できるって書いてあるんですか?
それと若干じゃなくて大幅にスレ違いです。

200:デフォルトの名無しさん
08/04/05 02:37:46
いいえ、スレ違いではありません。鼬害です。

201:デフォルトの名無しさん
08/04/05 06:19:59
>>198
「ツール」メニューの「コマンド実行」を使う。

下パネルから実行したとき、子プロセスの標準出力がうまく表示されない。
プロセスが終了するまで、子プロセスの標準出力の内容が表示されないようになっている。

202:デフォルトの名無しさん
08/04/05 15:08:33
そして板違いの指摘の後にレスする馬鹿。

203:デフォルトの名無しさん
08/04/05 21:37:05
>>201
ありがとうございます。

>>他
すみませんね、住人さん。自治会お疲れ様です。

204:デフォルトの名無しさん
08/04/06 01:47:50
#include <stdio.h>

main()
{
char ss[80];

gets(ss);
puts(ss);
}

文字を80文字以上入力しても、全ての文字が表示されるんですか
何故80文字以上gets()で読み込んでputs()で表示する事ができるのでしょうか

205:デフォルトの名無しさん
08/04/06 01:51:04
ss のサイズが 80 までなんて gets は全く知らないから
メモリを破壊してどんどん文字を保存していってしまう。
非常に危険。
gets は使っちゃダメ。代わりに fgets を使うべし。

206:デフォルトの名無しさん
08/04/06 01:51:05
オーバーフローした場合の動作は未定義だから。

207:204
08/04/06 02:01:05
なるほど!理解できました
ありがとうございます。

208:デフォルトの名無しさん
08/04/07 10:07:03
任意のURLからファイルをダウンロードしてくるプログラムを作ったのですが、(マルチスレッド+Winsock)
一回のダウンロードごとにメモリ使用量が5~30KBずつ増えていきます。
動的な確保は行っておらず、
何故増えていくのかがわかりません。
この場合の考えられる原因を教えて頂きたいです。

209:デフォルトの名無しさん
08/04/07 12:21:08
動的な確保を行っているから。mallocだけが動的確保じゃない。APIの呼び出しも動的確保になる場合がある。

210:デフォルトの名無しさん
08/04/07 12:29:59
Release~しないといけない所を忘れてるとか。

211:デフォルトの名無しさん
08/04/07 15:08:26
なるほど…盲点でした。
もう一つお伺いしたいのですが、
グローバル変数はあまり使わないほうがいい、
という事を聞いたので
URL名
SERVER名
PATH名
ディレクトリパス
を保つ構造体をmain内で宣言したのですが、
自作関数の引数をあちこち増やさなければいけなくなりまして…
これってまずいですか?
一般的に言われる汎用な関数とはどんな関数なのですか?

212:デフォルトの名無しさん
08/04/07 15:12:18
よくわからないけど通りすがりにレスすると
その構造体というかメンバ変数を持つクラスで管理すればいいんじゃないの?

213:デフォルトの名無しさん
08/04/07 15:20:04
C++じゃなくてCだから困ってるんじゃ

214:デフォルトの名無しさん
08/04/07 16:16:50
はい。Cです。

215:デフォルトの名無しさん
08/04/07 16:18:59
>>211
プログラムの性質も作りも判らないからなんともいえないけれど、main()から構造体のポインタを順次下請け関数に渡すだけでしょ。
最下層にまで届ける必要はないはずだし、普通はあんまり問題にならないと思うけど。

216:デフォルトの名無しさん
08/04/07 16:25:50
>>215
main内で構造体を宣言することって
よくあることなんですかね?

217:デフォルトの名無しさん
08/04/07 16:30:34
>>216
何も問題はないよ。


218:デフォルトの名無しさん
08/04/07 16:33:13
あ、Cのスレだった・・・すまん
多用しなければグローバル変数にした方が色々と便利&バグを生まない事もあるよ
その構造体1つだけとかならグローバルにしちゃうのがいいと思う

219:デフォルトの名無しさん
08/04/07 17:51:09
>>216
OKだよ。
構造体のポインタをがんがん渡していけばいい。
複雑になったら、そのとき単純にする方法を悩めばいい勉強になる。

220:デフォルトの名無しさん
08/04/07 18:58:34
全てのグローバル変数を、実体名"Global"で構造体にまとめると、
Global.totalとか、Global.countとか一目瞭然で便利。
って、物の本に書いてあった。一理あると思った。

221:デフォルトの名無しさん
08/04/07 19:01:01
そんな方法があったか

接頭句を「g_」にするより分かりやすいな

222:デフォルトの名無しさん
08/04/07 19:38:52
>>220
カテゴリー別に分けて構造体にして、わかりやすい名前をつければ尚良い。
グローバル変数依存からの脱却の第一歩だ。



223:デフォルトの名無しさん
08/04/07 20:20:03
C言語を作れて表示できる無料のソフトはないですか?

224:デフォルトの名無しさん
08/04/07 20:20:44
C言語を作るとな?

225:デフォルトの名無しさん
08/04/07 20:30:38
>>223
cygwin とgcc
visualstudio
bcc
好きなのを選べ
おすすめはしないが
LSI Cというのもある

226:デフォルトの名無しさん
08/04/07 20:30:47
Windows上で動く無償のCコンパイラ、とエスパーしてみると、いくつかある。

Visual C++ 2008 Express Edition
URLリンク(www.microsoft.com)

C++Builder
URLリンク(www.codegear.com)

「C++」と書いてあるが、C言語のソースのコンパイルもできる。
他にcygwinとか。


227:デフォルトの名無しさん
08/04/07 21:24:45
>223
読み直してみろ
「C言語をつくれて」
これおかしいだろ

C言語という言語をつくるのか?

人にまともな説明すらできないやつはプログラム組むの無理だからあきらめろ




228:デフォルトの名無しさん
08/04/07 21:27:09
入門編なんだから大目にみてやれよ

そこまで攻撃する意図がわからんよ

229:デフォルトの名無しさん
08/04/07 22:38:23
逆に、
このくらいエスパーできないやつはここで教えるの無理だからあきらめろ
とも言える

230:デフォルトの名無しさん
08/04/07 23:33:14
初心者です。意味がわからないかも知れませんが質問させてください。
配列なんですがaの添字に代入されてる数字をそれぞれbに該当するところに
転送する場合どうなりなすか?
例でいうとaの0番目にある3をbの3に入れるということです

a[0]=3 b[0]=0
a[1]=4 b[1]=1
a[2]=0 b[2]=2
a[3]=5 b[3]=3
a[4]=1 b[4]=5

231:デフォルトの名無しさん
08/04/07 23:36:11
for(i = 0; i > MAX; i++)
b[a[i]] = a[i];

232:デフォルトの名無しさん
08/04/07 23:36:16
mixiに、タブは機種依存文字と言い張る基地外が現れる。


233:231
08/04/07 23:37:50
不等号逆だった

234:デフォルトの名無しさん
08/04/07 23:38:22
a[0]~a[4]とb[0]~b[4]
の全部の例を書いてみてくれ

235:230
08/04/07 23:49:03
すいません訂正です。
a[0]=3 b[0]=0
a[1]=4 b[1]=1
a[2]=0 b[2]=2
a[3]=2 b[3]=3
a[4]=1 b[4]=4

a[0]=3→b[3]=3
a[1]=4→b[4]=4
a[2]=0→b[0]=0
a[3]=2→b[2]=2
a[4]=1→b[1]=1
に同じ番号のところに転送するにはどうするかという意味です

236:デフォルトの名無しさん
08/04/07 23:49:15
>>230

やっぱり言っている意味がわからん。

>例でいうとaの0番目にある3をbの3に入れるということです

b[3] = a[0];
ということだよね?と考えると、一瞬 >>231 (不等号を逆にして)でいい気がするが、
a[3] はどうするの?


237:デフォルトの名無しさん
08/04/07 23:51:26
>>235
結局は
b[i]=i;
になるんじゃないの?

238:デフォルトの名無しさん
08/04/07 23:52:35
>>235

「転送する」の意味がわからん。
b[0]~b[4]には元々値が入ってるんでしょ?
並びを
b[3]=3
b[4]=4
b[0]=0
b[2]=2
b[1]=1
としたって、配列の中身は
b[0]=0
b[1]=1
b[2]=2
b[3]=3
b[4]=4
と変わらないよ?


239:230
08/04/08 00:01:45
ん~なんと説明していいか…如何せん素人なもんで
aの0にある数字3をbの同じ3番目に当てはめる?
にはどうするかってことです。
同じくaの1にある数字4をbの4に当てはめるってことです

あの聞いといてなんですけど意味不だったらスルーしてください

240:デフォルトの名無しさん
08/04/08 00:09:33
素人とかの問題じゃないんだけどな
1回自分で全部代入してみてbの中身全部表示してみると分かると思うけど
b[0] = 0 b[1] = 1 b[2] = 2... となるだけ

241:デフォルトの名無しさん
08/04/08 00:10:35
>>239
暗号化がしたいのかな?

242:デフォルトの名無しさん
08/04/08 00:15:32
>>239
結局>>231>>237でいいような気がするが。

あと>>235が「配列bの添字の順番を換えたい」と言っているように思えるので、
一応、それは無理だと言っておく。
そもそも添字というのは「i番目」というような順番を示すものなので、
変更は不可能だ。

わかってるってんだったら、失礼。

243:デフォルトの名無しさん
08/04/08 00:33:18
b[0] = A, b[1] = B, b[2] = C
とあったものを、
a[0] = 1, b[1] = A
a[1] = 2, b[2] = B
a[2] = 0, b[0] = C
== b[0] = C, b[1] = A, b[2] = B
にしたいってことかしらん?
aの中身をbの添字にした時、正しい文字が現れるようにしたい、みたいな。


244:デフォルトの名無しさん
08/04/08 09:38:29
>>230
代入は上書きコピーのこと。転送とまちがえてはいけない。

245:デフォルトの名無しさん
08/04/08 12:33:58
>>230
何が目的なのかも書き込んだほうがいいんじゃない?
あんたのコード例から目的が推察できないのでみんな
首ひねってるんだと思うよ。

246:デフォルトの名無しさん
08/04/08 16:51:01
#include <stdio.h>

int main(void)
{
int n1, n2;
int per;

puts("二つの整数を入力してください。");

printf("整数 A:"); scanf("%d",&n1);
printf("整数 B:"); scanf("%d",&n2);

per = n1 / n2 * 100;

printf("Aの値はBの%d%%です。\n",per);

return (0);
}


実行結果を
2つの整数を入力してください。
整数A:50
整数B:100
Aの値はBの50%です。

と、したいのですが↑のプログラムじゃ動いてくれません;;
「Aの値はB の0%です。」
となってしまいます;;

何故でしょうか?

247:デフォルトの名無しさん
08/04/08 16:52:09
intは整数型だよ

248:デフォルトの名無しさん
08/04/08 17:05:41
50/100 = 0
0*100 = 0

249:デフォルトの名無しさん
08/04/08 18:38:07
>>246
整数型の計算は、コンピュータでは1より小さい結果になると
答えがゼロになるんだよ。なぜかといわれても、そういうもの
だと思ってくれ。

回避する方法は色々あるが、とりあえず

per = n1 * 100 / n2;

にしたらいい。理由は自分で考えてね。

250:デフォルトの名無しさん
08/04/08 19:45:39
ファイルを読み込み解析したいのですが、

char *buf = FileRead(file_path);

Kaiseki(buf);
free(buf);
または
Kaiseki(file_path);
にするか悩んでいます。
FileRead関数内で動的にメモリを確保して
確保した領域をKaiseki関数に渡し解析するか、
Kaiseki関数内にファイルへのパスを渡して
読み込み、解析をKaiseki関数内で行うか、
どちらが良いと思われますか?

251:デフォルトの名無しさん
08/04/08 20:13:45
inspect関数かinvestigation関数でやるのがいいと思うよ
マジレスすると場合によるからどっちともいえない

252:デフォルトの名無しさん
08/04/08 20:21:43
>>251
どのような場合があるのですか?

253:デフォルトの名無しさん
08/04/08 20:42:23
5P3
順列の総数を求めるプログラムを教えてください
考えすぎて頭が痛くナリマスタ
よろしくオナガイシマス

254:デフォルトの名無しさん
08/04/08 21:09:06
>>250

255:デフォルトの名無しさん
08/04/08 21:12:34
>>253
オーバーフローとか一切考えなければ
5!を3!で割るだけじゃんww
なにが分からないの?w

256:デフォルトの名無しさん
08/04/08 22:20:03
>>253
ほらよ。
#include <stdio.h>
#include <math.h>

double npm(int n, int m) {return tgamma(n + 1) / tgamma(n - m + 1);}

int main(int argc, char ** argv)
{
printf("%g\n", npm(5, 3));
return 0;
}

257:246
08/04/08 22:30:13
>>247-249
ありがとうございます。

258:デフォルトの名無しさん
08/04/08 22:31:58
>>252
>>252
>>252
>>252
>>252
>>252

259:デフォルトの名無しさん
08/04/08 22:32:53
T lPr(T l,T r){T r=1;for( T i=r+1; i<l; i++){ r *= i; } return r;}

260:デフォルトの名無しさん
08/04/08 22:34:25
>>259
おいw

261:デフォルトの名無しさん
08/04/08 22:48:02
バグがあるな。

262:デフォルトの名無しさん
08/04/08 23:08:45
>>256
そのままコンパイルすると
error C3861: 'tgamma': 識別子が見つかりませんでした
なのですが?

263:デフォルトの名無しさん
08/04/08 23:50:07
まともなCコンパイラを使ってください。

264:デフォルトの名無しさん
08/04/09 19:31:35
5! / 3! って結局 5 * 4 だろ?
一旦階乗求めるよりh(ry

265:デフォルトの名無しさん
08/04/09 21:23:09
hの続きは何だよ

266:デフォルトの名無しさん
08/04/09 21:26:20
// オーバーフローしにくいように書いてみた
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b){
int c;
while((c=a%b)) a=b, b=c;
return b;
}
int mPn(int m, int n){
int t, u=1, l=1;
if(m<1 || n<1 || m<n) return 0;
if(m-n<n) n=m-n;
for(;n>0;n--,m--){
l*=n;
t=gcd(u, l);
l/=t;u/=t;
t=gcd(m, l);
l/=t;u*=m/t;
// printf("m=%d n=%d [%d / %d]\n", m, n, u, l);
}
return u/l;
}
int main(int argc, char *argv[]){
int m, n;
if(argc!=3) return 1;
m=atoi(argv[1]);
n=atoi(argv[2]);
printf("%dP%d=%d\n", m, n, mPn(m, n));
return 0;
}

267:デフォルトの名無しさん
08/04/09 21:42:27
定番のhello worldがなぜか実行されない。。。

#include <studio.h>

int main(void)
{
printf("hello, world\n");

return 0;
}

エラーE2209 sample.c 2: インクルードファイル 'studio.h'をオープンできない
警告 W8065 sample.c 6: プロトタイプ宣言のない関数 'printf'の呼び出し(関数 main)
*** 1 errors in Compile ***

と、何度試行を繰り返してもなります;
このエラーをどう訂正していいのかわからない超初心者です。
設定などもチャート通り何度もやり直しましたが、上手くいきません。
よろしくお願いします。

268:デフォルトの名無しさん
08/04/09 21:47:43
studio......

269:デフォルトの名無しさん
08/04/09 21:48:54
standard I/Oな

270:デフォルトの名無しさん
08/04/09 21:48:55
エラーで気付や

271:デフォルトの名無しさん
08/04/09 21:49:17
あるあるww

272:デフォルトの名無しさん
08/04/09 22:03:37
DWORD gdw1;
DWORD gdw2;

gdw1 = timeGetTime();
//処理
gdw2 = (timeGetTime()-gdw1);
printf("%d",gdw1);
としても毎回計測するごとに処理時間が増えているのですが、
何故なのでしょうか?

273:デフォルトの名無しさん
08/04/09 22:07:55
質問の意味がよく分からんが
purintfにgdw2を渡すべきなんじゃない?

274:デフォルトの名無しさん
08/04/09 22:08:49
gdw2を表示したいんじゃないの?

275:デフォルトの名無しさん
08/04/09 22:20:14
Cのみだったのでこちらで質問させていただきます。
現在、下記のような感じでプログラムを作ってるのですが、
URLリンク(kansai2channeler.hp.infoseek.co.jp)
2つ問題があり、
①入力していくと次の配列まで入力されてしまう。
②2つ目のエラー仕様をどこでどう記述していいのか。
初歩的なことで、無駄な文が多いかもしれませんがよろしくお願いします。
また、こうすればもっと判りやすくできるなどあったら教えて欲しいです;

276:デフォルトの名無しさん
08/04/09 22:54:48
>>275
「次の配列」が何を指しているのか判りませんが、一文字ずつ入力してチェックするのは標準入力では無理があるかと。
普通に1行入力してから、解析する方がたぶんましです。

277:デフォルトの名無しさん
08/04/09 22:55:24
>>275
....
break;
}
}
if((cnt <= 0) && ((c == '-') || (c == '\n'))) {
printf("エラーメッセージ");
exit(1);
}

if(x == 1){
.....


278:デフォルトの名無しさん
08/04/09 23:10:17
>>275
>また、こうすればもっと判りやすくできるなどあったら教えて欲しいです;
うまく関数化しよう。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int absolute(int n1, int n2) { return n1>n2 ? n1-n2 : n2-n1; }
void check(const char* s)
{
    int i;
    for(i=0; s[i]; i++) {
        if( !isdigit(s[i]) && s[i]!='-' ) { puts("不正な文字"); exit(EXIT_FAILURE); }
    }
    if(!s[0] || strcmp(s, "-")==0) { puts("数値ではない"); exit(EXIT_FAILURE); }
}
int input(void)
{
    char str[100];
    scanf("%99s", str); check(str); str[ str[0]=='-' ? 9 : 8 ] = 0; return atoi(str);
}
int main(void)
{
    int a, b;
    printf("数値a="); a=input();
    printf("数値b="); b=input();
    printf("%dと%dの差の絶対値は%d\n", a, b, absolute(a,b));
    return 0;
}

279:デフォルトの名無しさん
08/04/09 23:41:13
int input(int *p){
char str[100], *pstr=str;
int value, index=0, sign=1;

if(scanf("%99s", pstr)!=1){
puts("入力エラー");
return 0;
}
if(sscanf(pstr, "%d%n", &value, &index)>=1 && pstr[index]=='\0'){
if(*pstr=='-') sign=-1,pstr++;
sscanf(pstr, "%8d", &value);
if(p) *p=sign*value;
return 1;
}
printf("不正な文字 %s\n", &pstr[index]);
return 0;
}

280:275
08/04/09 23:49:48
>>276
a[0],a[1]でa[0]の入力をすると、a[0]の上限をこえたとき(cnt以上)に、
そのままa[1]の中身まで入力されてしまうってことですね;

>>277
break;のとこもexit(1);にし、int exit(int);を入れてみたところ、
そこはかとなく②の部分はできました。ありがとうございますー。

281:281
08/04/10 14:58:40
わからないので教えていただけないでしょうか
URLリンク(kansai2channeler.hp.infoseek.co.jp)
よろしくお願いします。

282:デフォルトの名無しさん
08/04/10 15:01:38
史上稀に見る課題の丸投げ具合ですね

283:デフォルトの名無しさん
08/04/10 15:13:06
自分でわかろうと努力をするつもりはないわけか
課題の言葉の意味もわかってなさそうだ

284:デフォルトの名無しさん
08/04/10 16:17:51
>>283
社会に出れば、問題を解決する方法論を持っていればそれが能力と
みなされる。
たとえその方法論が丸無げであってもな。

285:デフォルトの名無しさん
08/04/10 16:29:12
その友達に聞け

286:デフォルトの名無しさん
08/04/10 16:30:45
AもBもやったことない俺に、Cなんて聞くんじゃねぇ~ぞゴルァ!
C言語ならおk

287:デフォルトの名無しさん
08/04/10 18:57:28
Cとかまだやってんのwだっさw

288:デフォルトの名無しさん
08/04/10 19:36:17
スタックが32バイトしか取れないからしょうがないのだ。

289:デフォルトの名無しさん
08/04/10 23:47:00
>>288
それはアセンブラでもきびしいだろw

290:デフォルトの名無しさん
08/04/10 23:54:53
簡単なリモコン作る程度なら多いくらいだ

291:デフォルトの名無しさん
08/04/11 11:43:11
ファイル名を入力して、そのファイルの小文字を大文字に置換した結果を
別のファイルに出力するプログラムです

ソース
URLリンク(arhp.hp.infoseek.co.jp)

出力されたモノ
URLリンク(arhp.hp.infoseek.co.jp)

見ての通り日本語が化けてしまいます
どうすれば正しく表示されるでしょうか?
もっと簡単に出来るやり方があればそれも教えて欲しいです

ちなみに
if(ch == komoji[a]) {
fputc(omoji[a],outfp);
のkomojiとomojiを入れ替えて大文字→小文字のモノを作ろうとしましたが
さらに日本語がおかしくなりました

まだ入門書を半分も読んでいない初心者が思いつきでやったので
色々突っ込みどころはあるかと思いますがよろしくお願いします

292:デフォルトの名無しさん
08/04/11 12:45:21
漢字は2バイト以上で表現しているのだゾ。
漢字コードでググルのだ。


293:デフォルトの名無しさん
08/04/11 13:07:06
>>291
当方で確認した環境は WindowsXP, 使用した処理系は cygwin(gcc 3.4.4) です。
以下のプログラムで問題が発生するかどうか、確認してみてください。
問題が発生しなければ、これが解決方法です。
URLリンク(kansai2channeler.hp.infoseek.co.jp)

古いし、問題もあるようですが、参考にした書籍をあげておきます。
応用C言語, 三田 典玄, アスキー 1988, ISBN4-7561-0056-2
第3章

294:デフォルトの名無しさん
08/04/11 13:13:56
>>291
突っ込みどころ満載だな。
・komoji, omojiは配列にする必要がない。const char * komoji = "abcde...z"でいい。
・bについては、要素数を固定値で持つな。ましてそれを変数に代入するな。
・forの条件もおかしい。このまま直すならa < bではなくa <= bだが、そもそもここはkomoji[a] != '\0'にすべきだ。
・strcpy(), strcat()を並べて使うくらいならsprintf()でも使え。この場合、sprintf(newfilename, "h_%s", filename)でいい。
・fgetc()の戻り値をcharで受けてはいけない。fgetc()の仕様を確認すればわかるが、intで受けるべきだ。
・cも要らない。小文字と判断したときにfputc()するのではなく、その場はchを書き換えておくだけでいい。
・>292も書いているが、Windowsで普通に扱う文字コードでは漢字コードの一部が英小文字に一致してしまう。
 真面目に対処すると意外に面倒だから、他の問題を全てクリアしてから改めて挑戦しろ。

295:デフォルトの名無しさん
08/04/11 13:17:08
>>293
その本はゴミだ。いや、作者がゴミそのものだ。

>>291
>293を見て気付いた点をもう一つ追加。
・小文字と判断したら、forからは脱出しておけ。
・gets()は使うな。fgets(filename, sizeof(filename), stdin)にしておけばいい。

296:293
08/04/11 13:29:55
>>295
まあまあ、せっかくソースをさらして質問している(質問作法としては最上です。)のだから、
まずい点をことさらに列挙するのはどうでしょうか。

それはそうと、
fgets() の第一引数はファイル名ではなくて、バッファなんですけど。

> その本はゴミだ。いや、作者がゴミそのものだ。
netnews の時代からいろいろいわれていたようですけど、
具体的にどこが悪いんでしょうか。おしえていただけるとうれしいです。


297:デフォルトの名無しさん
08/04/11 13:36:34
まあ環境依存だよな
漢字というか多バイトコードが何なのかによって変わっちゃうから

298:291
08/04/11 13:36:57
いえいえ、具体的に間違いをあげて頂きとても助かりました!
今からお二人のアドバイスを参考にやってみます!

299:デフォルトの名無しさん
08/04/11 13:37:55
入門で作るプログラムとしてはASCII以外を考慮するのはハードル高すぎると思うよ

300:295
08/04/11 13:39:07
>>296
もうかなり前だから何を以ってゴミと判断したかは忘れたが、
当時本人にも直接メールして本の不備を詳細に指摘したことがある。
言い訳だけが返ってきた。

それはそうと。
>fgets() の第一引数はファイル名ではなくて、バッファなんですけど。
もとのソースを見たか?
> gets(filename);
これ以上必要もない恥の上塗りはやめておけ。

>まずい点をことさらに列挙するのはどうでしょうか。
真摯に聞く態度を示す質問者だからこそ、列挙した。
つーか、「まずい」と認識しつつ指摘しない方が不親切だろ。

301:291
08/04/11 13:41:58
環境依存ですかー
やっぱり初心者がやるにはちょっと面倒なモノだったようですね
皆さんの言ってることがある程度理解出来たら自己満足したいと思いますw

302:293
08/04/11 13:43:00
>>296
あっ失礼、filename というのは、提示されたプログラムの変数をさしていたんですね。
もうしわけない。

303:293
08/04/11 13:47:03
>>300
そうですね。gets() はまずいですね。
提示されたプログラムでは、128 文字以上入力されるとおかしくなってしまいます。

> 真摯に聞く態度を示す質問者だからこそ、列挙した。
> つーか、「まずい」と認識しつつ指摘しない方が不親切だろ。
たしかに。


304:デフォルトの名無しさん
08/04/11 13:49:09
EUCだと3バイトとかあったっけ?

305:295
08/04/11 14:03:04
>>304
入門の域を超えるから自分で調べてくれ。

と、それでは不親切なので、Asciiと共存できる文字コードを簡単に。
# つーか詳しくないので間違っていたら失敬。

・シフトJIS、SJIS、CP932、MS漢字など
Windowを中心に広く使われる。基本的に漢字などは2バイトで表現できるが、
2バイト目のコードがAscii文字の領域に重なるために何かと厄介。
特に、大文字小文字変換やディレクトリの区切り(\)のためにバグが出た商品も多々ある。

・(狭義の)EUC、EUC-JP
一部のUnixなどで使われる。狭義のEUCでは基本的に漢字は2バイトだが、
(所謂)半角カナも2バイトになってしまう罠。広義のEUCはEUC-KRなどの日本以外のものも含む。

・UTF-8、(狭義の)Unicode
最近のLinuxやMac(これも実はUnix系)などで一句使われる。基本的に漢字などは3バイトになる。
厳密に解釈しだすと切りがないので省略。UTF-8以外のUnicodeとは表現方法が随分異なる。

・ISO-2022-JP、(狭義の)JIS
メールなど、7ビット通信環境でも使えることを前提とした環境で使われる。
漢字などはasciiと同じような範囲を使うので単純にチェックすることは不可能。
asciiとの境界にEsc符号列を用いることで状態を切り替えるので、手間さえ掛ければ勿論チェック可能。
但し、改行前後でAsciiに戻さないといけないなど制約が多いので、内部コードとして使うことはお勧めできない。

306:293
08/04/11 14:08:01
>>305
補足。
>>293 ではシフトJIS(MS漢字コード)の古い時代のものを仮定しています。
>>293 で作成・検証に使用したコンパイラは、まさにシフトJIS には対応していない
ので、提示されたプログラムにある日本語メッセージは、なくなく削除しました。

307:デフォルトの名無しさん
08/04/11 14:18:05
>>306
cygwinなら、gccのオプションに--input-charset=cp932 --exec-charset=cp932を書くといいかも。
応用で、EUCで書かれたソースをcygwin用にコンパイルすることもできますぜ。

308:デフォルトの名無しさん
08/04/11 16:45:27
>>307
感謝です。gnu の libiconv/iconv_open() の指定方法でいけばいいんですね。
またひとつ賢くなりました。

309:デフォルトの名無しさん
08/04/11 20:16:02
>>287
Aどころか女と付き合ったこともないお前が言うと笑えるw

310:デフォルトの名無しさん
08/04/11 20:34:22
ワシのCは108手までまであるぞ

311:デフォルトの名無しさん
08/04/11 21:18:17
本当に初歩的な事ですみません…
C#ってなに?

312:デフォルトの名無しさん
08/04/11 21:20:08
プログラム言語

313:デフォルトの名無しさん
08/04/11 22:40:22
そのプログラムの中のたとえばどのようなものか教えていただけたらありがたい。

314:デフォルトの名無しさん
08/04/11 22:40:40
日本語でおk

315:デフォルトの名無しさん
08/04/11 22:45:33
自然言語に日本語、英語、フランス語と色々あるように、
プログラムを記述するのに使う言語も色々ある。
その1つがC#。もちろんCも1つの言語だ。

316:デフォルトの名無しさん
08/04/12 00:00:10
Cよりはjavaに近い言語ってよく言われてるね
まぁC#とか触ったこともないけどなw

317:デフォルトの名無しさん
08/04/12 00:28:35
JAVAっぽいC++

318:デフォルトの名無しさん
08/04/12 01:04:35
マイクロソフトのマイクロソフトによるマイクロソフトのために作られた言語


319:デフォルトの名無しさん
08/04/12 12:44:08
J++の焼き直し言語がC#

320:デフォルトの名無しさん
08/04/12 12:52:04
どの言語だろうと、基本的な部分は共通しているし
実装されている、出来ることを知ることの方が重要。
あとは、用意されているライブラリをきちっと使えれば、どの言語だろうと関係ねぇ
限定した言語でしか通用しないような奴は、どこへ行っても使い物にならない。
とりあえず、コンピュータの仕組みを知ることが出来たんで、大学に通っておいて正解だったぜ。

321:デフォルトの名無しさん
08/04/12 14:10:50
と、突然どうした。。。

322:デフォルトの名無しさん
08/04/12 14:15:56
簡単な文字出力のプログラムを作ったとして、
それをチャット上などで動作させることはできないのですか?
コマンドプロンプトの中でしか出力できないのですが

323:デフォルトの名無しさん
08/04/12 14:17:00
>>322
そう。

324:デフォルトの名無しさん
08/04/12 14:34:24
>>322
チャット上に文字出力するプログラム作ればいいじゃん

325:デフォルトの名無しさん
08/04/12 14:36:31
>>324
出力先をコマンドプロンプトじゃなくて、チャット上にするやり方が分からない
本にもそういうの載ってないんだが
すべてが独学だから聞く人もいないし・・

326:デフォルトの名無しさん
08/04/12 14:38:40
>>322
そのチャットソフトが外部プログラムを呼び出すようにできていれば、可能かもしれない。
# まぁ無理だ。

327:デフォルトの名無しさん
08/04/12 14:40:46
>>326
そうなんですか?teacupチャットだけど
ホットコーヒーのやつでは出来てたような。。。
とりあえず外部プログラムを呼び出すようにできてるかも分からないので、もちと勉強してきます!
ありがとうございました!

328:デフォルトの名無しさん
08/04/12 21:26:46
名古屋近辺の専門学校でC言語学びたいと思うんだけど、どこがあるか紹介して。
または2チャンネルのスレッドでそういうスレがあったらきぼん。

329:デフォルトの名無しさん
08/04/12 21:27:35
>>328
大学へGO!
やっぱり基礎が大事だから

330:デフォルトの名無しさん
08/04/13 07:30:38
C言語で操っている、操作させている、制御しているコンピュータの基本的な仕組み
そして極め付けが、君が日ごろ見ている文字、絵、動画、音声、それらはすべて
ある法則に則って記録された数値データ、その数値データを人間で言う動物細胞
物質の原子レベルまで追求して話をすると、0と1の組み合わせ、すなわちバイナリーデータとは
0と1、あるかないか、磁石で言う+と-、電気信号でそれらを管理、制御しているのさ。
ほら、いつもニヤニヤしながら見ているエロ画像、それがだんだん・・・ただの色の集まり、
その色は0と1の組み合わせで構成されているデータに見えてきただろ?
PCに色や文字、音声が人間が解釈できる形で表現できる機能が実装されているから
その0と1の無機質なデータがエロ画像に見えるのさ。グロだろうと。

331:デフォルトの名無しさん
08/04/13 09:52:55
人間なんて所詮炭素と水なのさ

という話と同等のどうでもいい話

332:デフォルトの名無しさん
08/04/13 10:06:34
その通り、しかし、それを理解してそれに対して適切に制御、操作できれば
可能な範囲内で様々なことが出来るようになる。だから基本に戻れと。
ただ・・・人間も、いくら美人だろうとイケメソだろうが、所詮最後は朽ち果てて
この世から存在すらなくなってしまうのさ。ほら、躊躇してねーで、とっとと
好きなプログラムを作れ。そしてエロ画像で好きなだけはぁはぁしてろ、な?

333:デフォルトの名無しさん
08/04/13 10:08:37
>>332
生きた証をどう残すかだな。子孫か、グレートコードか。

334:デフォルトの名無しさん
08/04/13 10:10:29
なんで択一なんだよ
両方ゲットせいよ

335:デフォルトの名無しさん
08/04/13 10:11:39
もちろん両方残せるのが一番良い。

336:デフォルトの名無しさん
08/04/13 10:13:58
おまえら何の話してるんだよ

337:デフォルトの名無しさん
08/04/13 10:20:13
自分も可能な範囲で子供を作れるのさ、作られるものは
遺伝子レベルでのことになるが。

338:デフォルトの名無しさん
08/04/13 14:32:55
returnとか戻り値とかどういうときにどう使うんですか?
詳しくかつ解りやすく教えてください

339:デフォルトの名無しさん
08/04/13 14:43:45
自作した関数は式の中で使えるんだよ。

340:デフォルトの名無しさん
08/04/13 15:17:19
int main()

341:デフォルトの名無しさん
08/04/13 15:21:39
int sankaku(int teihen, int tkasa)
{
return teihen * takasa / 2;
}

int main()
{
printf("%d", sankaku(10, 50));
return 0;
}

342:デフォルトの名無しさん
08/04/14 18:18:42
ソースURLリンク(kansai2channeler.hp.infoseek.co.jp)
ヘッダファイル(Macの方はこれがないと実行できません)URLリンク(kansai2channeler.hp.infoseek.co.jp)

内容は1~9の数字を表示して、中に入っていない数字(3が表示されていないなら3)を入力する簡単なゲームです
このままだと最高記録と、最後に終了した時刻を書き込むだけなのですが
いままでの記録のベスト10と、それぞれに対応した終了時刻を扱えるに変更したいです

最初にfread,fwrite関数で記録の要素数を計ってプログラムを組んだのですが
正常に読み取り、書き取りができませんでした
その時のコードを載せればいいのですが、そのままだといくつか変更しないとエラーが出るので正常に動くソースをさらしました
できるだけ簡単に記録のベスト10と、それぞれに対応した終了時刻を扱える方法を教えてください

343:デフォルトの名無しさん
08/04/14 21:33:40
どんどん流れてくるデータ列を、指定された割合で「バランスよく」
間引く方法で悩んでいます。

割合を%で指定された場合に、データ処理時に以下のようにしたのですが
int a = (clock() % 100) + 1;
if(a > DROPRATE) { ; }

これだと50%を指定したときに(0がFALSEで1がTRUEだとして)
000000111111000000111111
という感じに並んでしまい、
010101010101....
とはなってくれません。

出来るだけきれいに固まりが出来ないように間引くのには、通常どんな方法を
とればよいのでしょうか?

344:デフォルトの名無しさん
08/04/14 21:33:41
>>342
先ず、get_data()を改修してみよう。
fscanf()の使い方はそのままで、そこで得たbest, yearなどを格納できるように構造体配列を用意するのを忘れずに。
それができたら、テキストエディタで現在のkiroku.txtを編集してダミーデータを作ってそれを喰わせてみよう。
ここまでできれば、後はput_data()を改修して、記録の取り扱いのロジックを書けばいい。

要は、1件扱うのも10件扱うのも同じこと。
fscanf()とfprintf()で作っているのなら別途fread(), fwrite()が必要になるなんてことはない。

345:デフォルトの名無しさん
08/04/14 21:41:57
>>343
なんで clock なんか使ってるの?
rand 使えば?

346:デフォルトの名無しさん
08/04/14 21:44:43
いえ、randomで書いて、やっぱり固まり部分が出きるので
きれいにならぶ規則性がほしいな、と思っているのですが・・・
三角関数とか使うのは嫌だし・・・

347:デフォルトの名無しさん
08/04/14 21:45:11
>>343
clock() に DROPRATE を掛ければ委員ジャマイカ?

348:デフォルトの名無しさん
08/04/14 21:48:25
>>346
バケツ変数みたいなものを用意して、毎回通過時にDROPRATEずつバケツに足していくとか。
勿論、バケツが一杯になったら空にすればいい。
Ex.

static unsigned bucket = 0;
bucket += DROPRATE;
if (bucket >= 100) {
bucket = 0;
flag = true;
} else {
flag = false;
}

349:デフォルトの名無しさん
08/04/14 21:51:05
データ列の速度が1じゃないとだめか。
こうか?
a = (a+DROPRATE) % 100;
if(a > DROPRATE) { ; }

350:デフォルトの名無しさん
08/04/14 21:57:40
リサンプルにおけるエイリアシング現象じゃないの。

351:デフォルトの名無しさん
08/04/14 22:05:02
>>346
なるほど。規則的にしたいのか。
a 中に b 個 1 が規則的に出てきて欲しいのであれば、

void ab(int a, int b) {
for (int i = 0; i < a * b; i += b) {
printf("%d", (i % a < b));
}
printf("\n");
}

とかどうよ。

352:デフォルトの名無しさん
08/04/14 22:06:05
コメントありがとうございます。
>>347
 すみません。良くわかりません。
>>349
 なるほど、これだと確かに固まりが分散しそうですね。やってみます。

353:デフォルトの名無しさん
08/04/14 22:07:45
>>343
規則的でよければブレゼンハムのアルゴリズムが使えるよ
乱数要素を混ぜるならバッファ付のディザリングみたいの使えばおk

354:デフォルトの名無しさん
08/04/14 22:08:24
>>351
 ありがとうございます。やってみます。

355:353
08/04/14 23:02:19
>>343
いまさらだけど…
>>351 と同じインターフェイスで

void ab_(int a, int b){ // ブレゼンハム
int i, x;

for(i=0,x=a/2;i<a;i++,x+=b+1){
printf("%d", (x>=a));
if(x>=a) x-=a;
}
printf("\n");
}

double uniform_rand(void){return (double)rand()/(RAND_MAX+1);}
void ab__(int a, int b){ // 乱数ディザリング
int i, d;

for(i=0;i<a;i++){
d=0;
if(uniform_rand()*(a-i)<b) d=1,b--;
printf("%d", d);
}
printf("\n");
}

356:デフォルトの名無しさん
08/04/14 23:52:21
>>355
 ありがとうございます。参考になります。

皆さんへ
 結局、>>351さんのループ部分をばらした関数を作って使いました。
 どうもありがとうございました。

357:デフォルトの名無しさん
08/04/15 00:24:57
>>353
347=349だけど参考になった。
ブレゼンハムのアルゴリズムっていうのか。

358:353
08/04/15 14:25:42
>>357
参考にするなら訂正しておくよ orz
void ab_(int a, int b){ // ブレゼンハム
int i, x;

for(i=0,x=(a+b)/2;i<a;i++,x+=b){
printf("%d", (x>=a));
if(x>=a) x-=a;
}
printf("\n");
}

359:デフォルトの名無しさん
08/04/15 23:37:51
getchar()を使用し、絶対値を返すプログラムを作れ、ということで
ここでいろいろ参考にして、一応作ってみました。
結果は問題ないと出るのですが、イマイチ無駄な処理が多いかなと自信なくて、
修正できるとこがあれば、自分が判りそうな範囲で修正して教えてくださいー;
URLリンク(kansai2channeler.hp.infoseek.co.jp)

360:デフォルトの名無しさん
08/04/15 23:38:59
宿題スレ池

361:278
08/04/16 00:14:15
>>359
だから関数化しようって。
無駄な処理を言うなら、フラグを駆使してまでmainだけで頑張ることが無駄。
278のをgetchar使うように修正しといたから。
URLリンク(kansai2channeler.hp.infoseek.co.jp)

362:359
08/04/16 00:21:36
>>361
すみません、わざわざありがとうございます;

363:デフォルトの名無しさん
08/04/16 00:55:50
質問お願いします。
#include <stdio.h>

int main(void)
{
  int x[80],y[80];
  int a=-400,b=-400,lp,c=0;
 
  for(lp=0;lp<40;lp++){
     x[c]=a;y[c++]=b;
     x[c]=a;y[c++]=-b;
     a+=20;
     }  
  for(lp=0;lp<80;lp++){
     printf("x[%d]=%d y[%d]=%d\n",lp,x[lp],lp,y[lp]);
     }
  system("PAUSE");
  return 0;
}
上のプログラムで、ループを使って配列変数に値を代入する部分で、
最初のループでyに値を代入する時、y[c++]にbの値を代入するようになってますが、この時cに+1されているはずなのになぜy[0]の部分にbが代入されるのでしょうか?
一応、線を引くための座標を代入させるのが目的なので、y[0]に代入されて正解なのですが、どうしても気になったので質問させていただきました。分かりづらい説明かもしれませんがどうかお願いします。

364:デフォルトの名無しさん
08/04/16 00:59:37
>質問お願いします。
日本語でおk

c++ は cの値を取り出して使った後で、 cの値が+1 となる
つまり上記のy[c++]=bは c=0であれば y[0]にbを代入した後に、c=1 となる
おk?

365:デフォルトの名無しさん
08/04/16 01:00:47
>>363
x[c]=a;
y[c++]=b;

これの前中後それぞれに、cの値を表示するprintf文入れりゃわかるよ。

366:デフォルトの名無しさん
08/04/16 01:08:38
y[c++] = b だと y[c]←b の後に cを1加算  つまり y[0] == b
y[++c] = b だと cを1加算した後に y[c]←b つまり y[1] == b

367:デフォルトの名無しさん
08/04/16 01:08:52
>>365
前後じゃわからんだろう

368:363
08/04/16 01:21:50
>>364-366
++の位置で1を加算するタイミングが変わるのですね。
理解することが出来ました。ありがとうございます。

369:デフォルトの名無しさん
08/04/16 02:47:52
>>359
すでに指摘されていますが、absolute() とするのならば、input() なども作るのはどうでしょう。
桁数切り取りの場合わけに苦労しているようですが、「数字部分で8桁」と考えればいいかと想います。エラー1, エラー2 の検出も簡単に記述できると思います。min, cnt, err が絡み合わないように整理したほうがいいでしょう。
9桁目以降で数字以外の文字が入力された場合は、題意としてはエラーにしたほうがいいかも?(これは仕様の読みの問題ですが。)

些細なことですが、
getchar() ( -> fgetc() ) の返り値は int です。
main の返り値は int がお約束です。

提示されたソースの手法に従うのなら、こんなのはいかが?
(確認環境 WindowsXP, 処理系 cygwin(gcc 3.4.4))
URLリンク(kansai2channeler.hp.infoseek.co.jp)

>>361
きれい‥‥。でも質問者は <string.h> 全般がわからなくてスルーしちゃったのかも。


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