
Ubuntu日本語フォーラム

ログインしていません。
ハードはDELLの12インチ・ミニノート、OSはubuntu9.10です。
C言語で、char型配列変数と乱数発生関数で、配列変数に"0"~"9"、"A"~"Z"(IとOを除く)の文字をランダムに入れ、表示させるプログラムを作り、コンパイル・実行をしました。
すると、コンパイル時にはエラー表示なし、ランダムな文字列表示後に、Segmentation fault と表示され、入力待ちになります。
何が問題で、どうすればいいのでしょうか?
尚、ランダムな文字列は他で使う予定で、ここで表示させたのは本当にランダムになっているかどうか確認するためです。
ubuntuの問題というよりC言語の問題かもしれませんが、お分かりの方、ご教授願います。
オフライン
残念ですが完全にC言語の問題です。ここで聞くべきではないでしょう。
また、segmentation faultという情報だけではC言語のトピックでも問題は解決しないです。
オフライン
9割9分、単なるC言語の問題(というか、ソースのバグ)だと思いますが・・・
「コンパイルでエラーが出ないこと」は、日本語でいえば、文法が正しいことです。
「希望したとおりに動くこと」とは、全くの別次元の問題です。
「わたしは東京都を着ています」という日本語の文章は、(品詞だけで判断すれば)文法的には正しいですが、おかしな文章 というのと似たようなもんです。
# IMEの辞書が持つように、細かな属性を持つ(東京都は地名である。着るの対象としてはふさわしくない)ことで、「これはおかしい」と判断することも可能です。
なぜか、「バグの取り方(調査の仕方)」を解説しているサイトってないんですよね・・・文法を順に並べ覚えるよりもよほど重要なんですが・・・
もし、どーしてもなんとかしなくちゃ という場合、ふさわしい掲示板に移動したうえで、ソースを載せるのが1番近道です。本人が「正しいはず」と思っているどこかが間違えていることになるので、「怪しい部分だけ載せる」というのは、意味がない可能性が高いことに注意してください(怪しいと思っているところは、本人もよく調べるので、大抵あってます・・・)
# ソースなしで原因が指摘できたら、TVに出られます。たぶん。
オフライン
#2,#3のおっしゃっている通りですが、とりあえずアレじゃないかな、、、
空の配列を読みに行っている。
代入する文字が10個なら配列は0からなので10個用意するには9とする。←まずココ
後は配列にセットするときと配列を表示するとき。
for文か何かでランダムに入れた文字を順に表示するときのカウンターの確認。
もし当たりなら配列数が固定なら数値の調整、変動するなら動的に配列を生成する。
例外処理も忘れずに。
外れなら、管理者から指導が入りますので、C言語プログラミング関係にソースを付けて質問して下さい。
オフライン
住みませんが、「9割9分」とは何の意味ですか。 日本語を勉強するまだ3が月ですげど。
オフライン
99%
100% = 10 割
10% = 1 割
10% = 1 割 = 10 分
1% = 1 分
1% = 1分 = 10 厘
0.1% = 1 厘
0.01% = 1 毛
オフライン
hir0 による投稿:
99%
100% = 10 割
10% = 1 割
10% = 1 割 = 10 分
1% = 1 分
1% = 1分 = 10 厘
0.1% = 1 厘
0.01% = 1 毛
hir0さん、ありがとうございます。
オフライン
多くの皆さんの回答、ありがとうございます。
C言語の解説書を、もう一度じっくり読んでみます。
オフライン
本を読むのもいいですけど、ちゃんとデバッガを使ってデバッグした方がいいかと。たぶんポインタを壊してるか、ヒープオーバーフローさせてしまっているかだと思うので。
お勧めのデバッカはどのようなものがありますか?
尚、C言語によるプログラムといっても、数十行程度の簡単なもので、C言語特有の再帰やユーザー定義関数呼び出し、ポインタの直接操作などは行っていません(それじゃCじゃない?)。
オフライン
私が昔やった間違いは、文字配列の終わりに終端記号(\0 だっけ)を入れ忘れたというものでした。
オフライン
デバッガではなく統合開発環境になりますが Anjuta なんてどうでしょうか?
[ur]http://anjuta.seesaa.net/article/50053068.html[/url]
う~ん、当たり外れは別にして(おそらく当たり)、原因の内容と(#4)その名称(#10)そして基本的な事柄の指摘(#3)を良く読んでデバッグして頂くと原因の究明がスムーズに行くと思います。
初歩的な問題であり、且つベテランでも起こしてしまう事の有るミスかも知れません。
原因の理解が無いとこれから先もハマりやすくなりますし、メモリの確保の仕方とプログラムの内容によっては悪意の有る事に利用されるかも知れません。
オフライン
>ランダムな文字列表示後に、Segmentation fault と表示され、入力待ちになります。
典型的な、Cプログラムでのミステイクだろうと思われます。
Cの文字列は、とても原始的で、終端文字( '\0’ )で終端された文字列(asciz)でなければいけません。
つまり、宣言した、文字配列の要素内に、終端文字を代入し終端していなければ、
出来上がった実行プログラムは、'\0'が現れるまで、文字列を表示しようとしますが、
システムから与えられた範囲外(Segmentation fault)にアクセスすることになるため、
システムが、強制的に、その実行を停止します。
>デバッカ
gdb が入ってます。
>統合開発環境
*日本語の扱いに難ありかも知れませんが、初心者には、KDE標準の統合環境Kdevelopが、一番、取っ付き安いのではかもしれない。
(KUBUNUでなくとも、KDEアプリをインストール、実行できます)
*Anjutaは、gtk、gnomeアプリ開発に向いた環境のような気がしますので、勉強、教育には向かない気がする。
*eclipsは、参考書、webページ多く、環境を構築できれば使いやすいと思う。
*覚えるのが、C言語の勉強より難しいかも知れませんが、emacsとかvimの環境内でのプログラミングが一番、Linuxポイかもしれない。
オフライン
Anjuta、kdevelop 4をそれぞれインストールしてみましたが、使い方が全く分かりませんでした。
ヤマ勘で少し操作してみましたが、ソースが壊れるのが心配で、それ以上進めませんでした。
尚、kdevelop 4をインストールする時に、インストール前と後に「不正なユニコードが使われています。報告をお願いします」という表示が出ました。
これは何ですか?
C言語の話になり、板違いかもしれませんが、char型の配列変数100個を用意し、その全てを使う場合には、実際には配列変数を101個用意し、最後の変数には'\0'を入れておかなければならないのですか?
オフライン
個人差も有りますが全て数分~数十分で確認できる事のはずですが。
取り敢えず、strcpyを用いたのなら自動的に書き込まれます。
main()
{
char a[10];
strcpy( a, "out");
printf("%s", a);
}
*a[0]~a[4]まで何が入っているか一つずつ確認してみる。
*配列の要素数を変更してみる。
*a[0]='o'
a[1]='u'
a[2]='t'
で実行してみる。
*a[3] に (NUL)= \0 を入れて実行してみる。
*先にも書いていますが配列要素に一つずつアクセスしているならば
要素数以上の数値を指定していないか、空の部分を表示させようとしていないか。
(書かれたコードも示さずに疑問を小出しにするとC言語の板でも解答貰えないかも)
オフライン
C言語の話になり、板違いかもしれませんが、char型の配列変数100個を用意し、その全てを使う場合には、実際には配列変数を101個用意し、最後の変数には'\0'を入れておかなければならないのですか?
使い方によります。
コンソールに内容を表示するときprintf見たいな関数を使うのであれば当然終端しておく必要があります。
putcharなどを使えば、それなりに対処することも可能でしょう。
#include <stdio.h>
int main(void)
{
char hoge[8];
int i;
for(i=0;i<8;i++){
hoge[i]=i+0x30;
}
for(i=0;i<8;i++){
putchar(hoge[i]);
}
return(0);
}とか。
あまりUbuntuに関連した話題とも思えないので、C言語についてはC言語の問題を扱うコミュニティー・フォーラムでお願い致したく。
Ubuntu上で使えるデバッガにどんなものがあるか、などは大歓迎です。
いわゆるIDE環境がややこしくて反って使いにくいとのことであれば、gdbの方がシンプルでよいかも知れませんね。
まずは、manコマンドの使い方を覚えて下さい。
man [section_number] [command_name or function_name or etc]
でsection指定でマニュアルを参照できます。
man 3 printf
man 3 putchar
man 3 puts
man 3 rand
などなどで、C言語の勉強もできるかと思います。
オフライン
Ubuntuに関係トピックが続くのはよいことではないですが、とりあえず個人的な経験からヒントになれば。
printf(),scanf'(),sscanf(),fscanf()など書式指定で入出力する関数の引数でアドレスを渡していないとSegmantation Faultがでます
int a = 0;
printf("Number=%d", a)
これだと変数aの値表示するつもりが、aの値をアドレスとして解釈するので、アドレス0を参照しようとしてSegmantation Faultとなる訳です。
正しくはこうです。
print("Number=%d", &a);
今回乱数を取得して文字列に変えているので、sscanf()を使用している可能性があります。
こんなことやってないか確かめてください。
int a = 0;
char[ str[10] = "";
a = getRandonNumber(); /* 乱数取得関数(仮) */
sscanf(str, "%d", a);
正しくは以下です。
sscanf(str, "%d", &a);
この辺もう一度確かめていただければと思います。
オフライン
すいません。
×char[ str[10] = "";
○char str[10] = "";
これだとコンパイルすらとおりませんね。
うっかりミスを身をもって表現してしまいました。
情けないです…。
オフライン
というかコードを貼ってもらうのが一番早いような。
後は誰かが解説する。
C言語板でない所に、誠に申し訳ありません。
具体的には、"0"~"9"の文字を3回で30文字、"A"~"F"の6文字、"A"~"Z"から"I"と"O"を除いた24文字の合計60文字をchar型配列変数に入れ、シャッフルしています。
#include<stdio.h>
#include<time.h>
int main(void){
char p[] = {"012345678901234567890123456789ABCDEFABCDEFGHJKLMNPRSTUVWXYZ"};
int i,j;
char w;
srand( (unsigned)time((NULL) );
for( j = 59; j>1; j-- ){
i = rand() % j;
w = p[i];
p[i] = p[j];
p[j] = w;
}
return(0);
}
実際には、シャッフルされた配列変数からさらにランダムに文字を選び、5文字からなる文字列を表示しています。
レスが長くなるのでここでは省略していますが、その部分の方に問題があるのかもしれません。
オフライン
Z80Bさん による投稿:
C言語板でない所に、誠に申し訳ありません。
あまり重要なことではないですが、ここは「板」と呼ばれるような場所ではないですよ。気にする人もいるので念のため。
for( j = 59; j>1; j-- ){
i = rand() % j;
w = p[i];
p[i] = p[j];
p[j] = w;
}の
p[i] = p[j];
じゃないでしょうか。"i < 59" が担保されていない。
すいません。嘘でした orz
i = rand() % j;
剰余ですね orz
それよりも
char p[] = {"012345678901234567890123456789ABCDEFABCDEFGHJKLMNPRSTUVWXYZ"};ですが、これスコープ大丈夫ですかね?
char p[] = "012345678901234567890123456789ABCDEFABCDEFGHJKLMNPRSTUVWXYZ";
にしていないのは何故ですか?
hmatsue さん による投稿:
まずは、manコマンドの使い方を覚えて下さい。
の補足ですが、manpages-ja manpages-ja-dev manpages-dev らへんのパッケージを入れておくと、いいと思います。
オフライン