fgets内部の実装にもよるが、普通はバッファに一文字でも
書き込んだ状況でEOFが来てもフラグを設定するだけで
NULLは返さず次回の同じFILE*にたいする呼び出し時に
NULLを返す設計が取られるんじゃないかと...
(標準仕様でもそれが期待されているようだし)
>>700 ファイルの終端に達している状態でfgets()を呼ぶとEOFを返す
>>700 意味を勘違いしてる
最後の文字までとりこむfgetsではNULLを返さず
その次のfgetsでNULLを返すの
質問です。
#include <stdio.h>
#include <string.h>
void main(void)
{
char name[5];
int len;
do{
printf("お名前を入力して下さい\t");
scanf("%s",name);
len = strlen(name);
} while(len>5);
printf("\nあなたのお名前は %s です。\n", name);
}
これでname[5]の配列に30文字くらい打ち込んで終了させると、
OSのほうから終了時にエラーが出されます。
メモリに打ち込んだ文字が残ってるからだと聞いたことがあるのですが、
これらの記録を消去して、エラーを出さないようにするにはどういうことをすればよいのでしょうか。
最初からname[200]くらいとっておく。
200以上入力しようとするやつは知らん
それか可変長だな・・・。
>>705 エラーがでるのはスタックに積んであるリターンアドレスをぶっこわしてるから
scanf("%4s",name);
とかやって、そもそも配列外にアクセスしないことが大事
>>706 その考えは身を滅ぼす。gets()を使うくらい、下策。
どうせscanf()を使っているのだから>708が妥当。
会社の研修の問題でもscanfは使わずにコーディングしなさい、だったぞ。
>>710 だからなんだってんだよ・・・・・・・・・・・・・
/ ( ●)(●) |
scanf は使わないのが常識だよ
printfも使わないのが常識
scanf 使いたいときは sscanf を使うのが鉄則
718 :
705:2010/05/06(木) 21:19:16
バグ取れました。
次からはsscanfにすればいいのですね、ありがとうございました。
>>715 printfの戻り値を毎回確認してからしゃべれ、クソが
>>719 なにも考えずにつかっていたが、printfって戻り値があったのかw
そりゃ関数だし
voidだとおもってたわ。
質問します。
#include <stdio.h>
#include <stdlib.h>
char *input(void){
int i; char aaa[8]; int count =0; char *bb="";
printf("番号入力する");
scanf("%07s",aaa);
fflush(stdin);
while (aaa[count]){
count++;
}
for (i=0;i<count;i++){
*(bb+i)=aaa[i];
}
return(bb);
}
int main (void){
int i; char *p;
i=atoi(input()); printf("%d\n",i);
p=input(); printf("%s\n",p);
return(0);
}
これで実行してみると、printf("%s\n",p);で表示される文字の5桁目だけ、数字が入力時から+1された状態になります。
何故このようなことが起きるのでしょうか。
正しい表示にするにはどうすればよいのでしょうか?
わぁお、char *bb="";*(bb+i)=aaa[i];
とんでもないことしてくれてるな
スーパースマートコーディング
それ以前に変数名を何とかしろよw
>>723 何をしたいプログラムなのかわからないが、差し当たりの問題点を指摘する。
char *bb=""; は、コンパイラによっては書き込み不可領域に配置される場合があり、
実行時に落ちる気場合がある。
また、"" のみで初期化した場合、確保される領域は 2 バイトであるため、バッファ
オーバーフローを起こす可能性がある。
これらを防ぐには、malloc() でメモリ領域を動的に確保するか、main() 側でバッファ
を用意して input() に渡し、そこに入力結果を書き込むようにする。
なお、malloc() を使用する場合は必ず呼び出し側 (こごては main()) で戻り値を
記憶し、入力結果が不要になった時点で free() すべき。
その他の指摘。
・fflush(stdin)は環境依存なので避けた方がいい。
・数値入力用関数を作る積もりなら戻り値は整数の方が使い易くないか?
・scanf()の書式指定で'0'なんてあったか? printf()系の書式指定とは互換性がないと思った方がいい。
・returnは関数じゃないから括弧はつけない方がいい。まぁ、どうしても括弧つけたいなら止めないが。
・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される。意味的に等価なbb[i]を使うべき。
・演習目的なら止めないが、文字列のコピーは専用の標準関数を使うべき。
えっ
ってのが全部なんだが……
>・fflush(stdin)
意図が分からないので書くべきコードでは無い
>・数値入力用関数
はてな
>・scanf()の書式指定で'0'なんてあったか?
あるといえばある
>書式指定とは互換性がない
何を今さら
>・returnは関数じゃない
何を今さら
>・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される
大変なところに迷い込んでしまいましたね、読みやすさを重視して時には間接参照しましょう
スワップ関数はマクロですか、memcpy()ですか、汎用ポインタですか
>文字列のコピーは専用の標準関数を使うべき
文字列のコピーをしようとしたわけでは無いかもしれない
といってみるテスト
>>731 何か勘違いしているようだから一言。
>>・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される
これは文字通り、*(p+i)と書かずにp[i]と書けということ。
厳格なコーディング規約ではこのほか、ポインタ演算も禁止される場合がある。
そうそう、scanf()の書式指定では'0'は特別な意味を持たないようだね。
単純に幅指定の一部と見做されるのかな。この辺りは仕様を読み直さないとなんとも言えない。
その他は趣旨が不明なので割愛。
>723
実行するとSegmentation faltでこけるよ。
色々おかしいところがありすぎて、何がしたいのかよくわかりません。
入力文字列を数値に変換したいように見えるが、atoi使ってイイなら
文字列をそのままつっこめばいいし、scanf使ってイイなら%d使えよ
という気がする。
ま、一番の問題は>724の指摘通り;
*(bb+i)=aaa[i];
だね。
bbは書き換え可能な有効な領域を指していない。
>732
「厳格なコーディング規約」ってのは何?
いずれにしても
・ポインタに対する単項の*演算子禁止
・ポインタ演算も禁止
っていうコーディング規約は賛同できない。
>これは文字通り、*(p+i)と書かずにp[i]と書けということ。
何が文字通りなのかわからんが、p[0]ではなく
*pと書くべきケースは、少なからずありますよ。
>ポインタ演算も禁止される場合がある。
揚げ足とるようですまないが、文法を厳格に解釈すれば、
p[i]は*(p + i)のシンタックスシュガーでしか無いので、これも禁止されるように
読めてしまう。こうなるとまともなコーディングは無理。
「厳格なコーディング規約」というからには、しょうもないつっこみを
受けないような、「厳格な」表現を使ってください。
>>734 知識不足は恥じゃないけどねぇ。
今出掛けるんで、あとで資料を提示するよ。
メモリ領域を確保したら動くようになりました。
ご指摘のとおり、数値文字のみを文字列型で入力させて
その文字列をメインで受け取る入力用関数を作れという演習目的の課題でした。
質問の仕方が悪くて混乱させてしまい、すみません。
ご指摘ありがとうございました。
宿題は宿題スレへ
738 :
デフォルトの名無しさん:2010/05/08(土) 12:43:57
読み込むテキストファイルには*.cと書いてあるのですが、
(仮引数で拾った文字列).cに置換する方法をご教授願えないでしょうか。
以下がソースです。
色々突っ込みどころがあると思いますが宜しくお願いします
#define LEN_MAX 256
int FileRewrite(char *proj_name)
{
FILE *fp;
char *search_p;
char replace_p;
char line_buff[LEN_MAX];
char tar_buff[LEN_MAX];
char rep_buff[LEN_MAX];
char source_name[LEN_MAX];
sprintf(source_name, "./%s/Source/%s.c", proj_name, proj_name);
if ((fp = fopen(source_name, "r+")) == NULL){
fprintf(stderr, "file open error...¥nexit status(-100)¥n");
exit(EXIT_FAILURE);
}
strcpy(tar_buff, "*.c");
while (fgets(line_buff, LEN_MAX, fp) != NULL) {
search_p = strstr(line_buff, tar_buff);
if (search_p != NULL) {
sprintf(rep_buff, "// %s.c¥n", proj_name);
rtn = fputs(rep_buff, search_p);
}
}
fclose(fp);
return (0);
}
>>738 ソースファイル内の *.c という文字列を全て置換するの?
ソースファイルのコメント中の *.c という文字列を全て置換するの?
740 :
デフォルトの名無しさん:2010/05/08(土) 13:02:17
>>739 ソースファイルのコメント中の *.c という文字列です。
紛らわしくて申し訳ないです。
*.cという文字列は読み込みファイルの中に1つしかないので全てでもアリだと思います。
>>740 Cでやるよりsedやawkでやった方が楽な気がするけど。
sed -e 's/\*\.c/proj.c/' source > destination
該当ファイルを検索する辺りから含めてシェルスクリプトで書けば管理も楽だろうし。
Cでやりたいなら、以下に注意。
--
・読み込みバッファと書き出しバッファの共有は無茶
仮令"r+"でオープンしても、読み込みと書き出しは混在できない。
1行読んだら読む前の場所まで巻き戻してから書けば書けなくはないが、
行の長さが長くなるので次の行(の先頭)を潰してしまう。
あれこれ気を遣うくらいなら、一旦別のファイルに書いた方がいい。
・「*.c」が含まれる行は本当にそのコメント形式だけなのか
例えば「// *.c (ここに重要なコメント)」のようになっていたら、
そのコメントを潰してしまうことになる。
そこに気を遣うくらいなら、「*.c」を置換するに留めるべき。
尚、置換処理自体はsprintf()で%*.*sを駆使すれば数行で書ける。
743 :
デフォルトの名無しさん:2010/05/08(土) 15:29:43
#include<stdio.h>
int main(void){printf("%[d]"[2+3-1])}
の計算cygwinでやったんですが、でてきません。
どこが間違ってるでしょう?
一〇進の計算です。4とでてきません
基礎すぎてすいません・・・
>>743 ・コンパイルエラーが出る場合はエラーメッセージを貼りましょう。
・何か参考にした資料があるなら明記しましょう。
まぁ、突っ込みどころは山ほどあるけど正解を以下に。
--
#include <stdio.h>
int main()
{
printf("%d\n", 2 + 3 - 1);
return 0;
}
--
尚、空白・改行は適宜変更してもいいが、記号類は省略も追加もしないこと。
745 :
デフォルトの名無しさん:2010/05/08(土) 15:43:40
>>744 レスありがとうございます。
ですが
それでやってみたところ
chmod:missing operand after `755'
Try `chmod--help'' for more inormation.c
とでてきたんですが??
755ってなんですか?ずっと755がでるんですが
>>741 「ポインタに対する単項の*演算子禁止」なんて規約が存在する、
というのは嘘でしたってことでいいのね?
>>745 コマンドラインパラメータの不足
C言語関係なし
コンパイル方法(打ち込む文字)が間違ってる
>>745 エラーメッセージを貼るときはきちんと貼りましょう。
また、自分が何をやったらそうなったのか、必要ならコマンドラインのコピーも交えて説明しましょう。
まぁ、最早Cの問題じゃないことは>747の言う通り。
このまま続けたいならエスパースレへ。
750 :
デフォルトの名無しさん:2010/05/08(土) 16:00:40
やってみたとは、プログラムの実行です。
gcc(ファイル名
>>744のソース)をするとerrorがでました。
コンパイルエラーというのはプログラムの中身にエラーがあるとき
出るのですよね?
chmodできないのはコンパイラか。
取り敢えず、コマンドラインを貼れないならソースファイル名を晒してみようか。
厳密に言うとコンパイラ本体じゃなくてコンパイラとリンカを呼び出すスクリプトがエラーを出してる
missing operandだからソースファイル名がちゃんと入力されていないか、
コンパイルエラーでオブジェクトが生成されなくてリンカの手前でエラーが出てるかだと思う
>>750 コンソールを全部引用しろよ
お前クラスの素人の場合、普通の人が想像もしないことを
やってるから、抜粋すると解決しない
だいたい勝手にchmodが動くわけないし、誰かの作ったMakefileを
流用してるとかで、どっかで起動してるんじゃねーの
754 :
734:2010/05/08(土) 18:37:34
>732 >741
参照資料を見たけどさ、
「ポインタへの整数の加減算は使用せず、確保した領域への参照・代入は[]を用いる
配列形式で行う。」
としか書かれていないよ。
ポインタ演算禁止とは書かれておらず、丁寧に
「ポインタの演算を行う場合には、ポインタの指す範囲に気を付ける。」
と書いてある。
技術用語には「厳格な」定義があるので、勝手にねじ曲げないように。
>728で挙げている、あなたの感覚はおおむね間違っていないが、
理由付けからは、根本的な理解の甘さがかいま見える。
そのせいで、色々つっこまれている。
今回引っかかった表現は
×「ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される。」
×「ポインタ演算も禁止される場合がある」
>750
すでにつっこみが入っているが、何をやっているのかさっぱりわからない。
>やってみたとは、プログラムの実行です。
>gcc(ファイル名
>>744のソース)をするとerrorがでました。
2行目でやっていることはコンパイルであって、プログラムの実行では無いぞ。
コンパイル中にchmodが勝手に走るなんてことは無いと思うけど。
>コンパイルエラーというのはプログラムの中身にエラーがあるとき
>出るのですよね?
chmod:missing operand after `755'
Try `chmod--help'' for more inormation.c
これはコンパイルエラーではない。chmodのエラーで、引数が無い
という意味。なんでchmodが出てくるのか、想像できない。
コンソールをそのままコピペして貼り付けてみたら?
もっともCの問題ではないと思えるが。
756 :
デフォルトの名無しさん:2010/05/08(土) 19:42:10
>>755 すまん、弟に聞いたらできたよ。
gcc OOO.c
a.exe
で実行でできた、あなたが間違ってるとかじゃなかったから
ごめん。
また来るよ。
757 :
デフォルトの名無しさん:2010/05/08(土) 19:44:13
今人いるかな?質問させていただきます
char型の'1'をint型の1にしたいんですけど、テストしたら49になってしまう
どうやったらいいです?
48を引きます。
759 :
デフォルトの名無しさん:2010/05/08(土) 19:47:08
>>758 今VBでやってるんだが、
ほかのコンパイルでもそれで結果同じになるならいいんだがどうなんです?
760 :
デフォルトの名無しさん:2010/05/08(土) 19:47:49
コンパイラーでした間違えた
761 :
>>757:2010/05/08(土) 19:57:04
ちなみにキャスト代入でやった
while文で、ひとつずつchar型の数字をint型にしたいんだがどうすればいいんだorz
ここはC言語スレです。
VBの質問ならVBスレへどうぞ。
763 :
デフォルトの名無しさん:2010/05/08(土) 20:08:23
VBでC言語やってるんだ
誤解させてすまぬ
>>761を読む限りではこんな感じ
int i, n[ 5 ];
char s[] = "12345";
for( i = 0; i < 5; ++i )
n[ i ] = s[ i ] - '0';
765 :
デフォルトの名無しさん:2010/05/08(土) 20:22:44
>>764 ありがとうございます!
あとでやってみます
>>761 char型の数字をint型に
int intsuji = charsuji - 48;
while文で、ひとつずつひとつずつ
何をしたいの?
767 :
デフォルトの名無しさん:2010/05/08(土) 20:29:30
>>766 char型に入ってる数字を一文字ずつint型にいれるっていうことを
配列でやってるんでなんか簡単にまとめられないものかとおもって;
>>767 やりたいことを具体的に書いた方がいいよ。
769 :
デフォルトの名無しさん:2010/05/08(土) 21:34:22
>>768 そうですね、あんまつたわらないしよくなかったとおもいます
こんどからそうします;
>>764 そのやり方でできました。ありがとうございます。
#include <stdio.h>
int main(void)
{
printf( "%d - %X + %o = %d\n", 398, 1FB , 327 ,398-1FB+37 );
return 0;
}
これどこが間違ってますか?cygwinでこれを実行したら前のプログラミングがでました。
間違えたプログラミングだと実行したら前やった実行がそのまま出るっぽいです。
>>770 1FB じゃなくて 0x1FB じゃないの?
レス早い、本当助かる。
なぜ0xをつけるんですか??!??!
あと質問ですが何故int main()っているんですか?
printfだけじゃだめなんですか?ただの数値計算なんですが・・・
すげぇww
できたwww0xつけたらできた。涙出てきたわ。ほんまありがとう
また来るよ。
二度と来るな
ひでぇ・・・w
1FBって16進だろ
16進ってことを表すのが0x
c言語はint main()っていれなきゃいけない
これは関数だからc言語は関数型言語
最初よくわからなかったものが
わかるとなんでわからなかったのかわからなくなる
18禁ゲームからエロシーン削除して家庭用に移植というくだらない事、最初にやったアホがいると聞いて
C言語では、プログラムがどこから始まるか、ちゃんと書かなきゃいけないルール。それがmain()
C言語を発明した人がそう決めた。
ほかの言語だとファイルの先頭からいきなり始まるやつもあるし、そういうわけわかんないルールを
覚えるのも含めてプログラミングの勉強だから。
JavaやC#よりはマシだな
782 :
デフォルトの名無しさん:2010/05/09(日) 07:49:11
entry は結局日の目を見なかったね
mainってただの慣習じゃないの
>>783 ちがうよ。規格で定められている関数だよ。
え?そうなの?
じゃぁWinMain使うときはどういう扱いなの?
単なるコンパイラの独自拡張
787 :
デフォルトの名無しさん:2010/05/09(日) 12:56:59
>>785 規格ではフリースタンディング環境に分類される
OS はないことになっているので、あくまで利用者定義ライブラリという位置づけ
質問します。
#include <iostream>
using namespace std;
static char *plus(char *fp_c, char *fp_c2);
int main()
{ char buf[]="ab,cde,fghi",buf2[100];
char *fp_c,*fp_c2;
fp_c=buf;
fp_c2=buf;
fp_c2=fp_c2+2;
*fp_c2=0x00;
strcpy(buf2,fp_c);
cout << buf2 << '\n';
fp_c,fp_c2= plus(fp_c,fp_c2);
fp_c2=fp_c2+3;
*fp_c2=0x00;
strcpy(buf2,fp_c);
cout << buf2 << '\n';
return 0;}
char *plus(char *fp_c, char *fp_c2){
return fp_c2++; //1進める
return fp_c=fp_c2;}
関数plusの中でポインタを1進める物を作ろうとしたのですが
実行すると、関数の中に入ってないのか、先頭のポインタに戻っているのか
上手くいきません。上手く関数を使いポインタを進めるにはどうしたらよいのでしょう?
警告、いや、エラーも出ると思うが、また、お笑いコードを書くなよ
っていうかスレチ
791 :
デフォルトの名無しさん:2010/05/09(日) 21:45:19
皆さんの知恵をお貸しください
今度学校の授業でモジュラス10ウェイト3のC言語のソースを書くことになったのですが、どのように入力した
数値を使ってチェックコードを導くのか苦戦しています。
どのような方法で考えればいいか教えてください。
日本語で
794 :
デフォルトの名無しさん:2010/05/09(日) 22:36:40
>>791 scanfで数値を取得して、後は粛々と計算で終了では?
何を苦戦しているのか全くわからない。
質問です。
すでに入力されている文字列"12345678"があるとして、 "1234"だけを表示させて後は表示させないにはどうすればよいのでしょうか。
%cで一つずつ表示しか思いつかなかったのですが、よい方法はありますか?
>>795 #include<stdio.h>
int main(void)
{
char buf[256]="12345678";
printf("%.4s", buf);
return 0;
}
797 :
デフォルトの名無しさん:2010/05/09(日) 23:34:54
printf("%.4s", "12345678");
5の部分を\0に書き換える
799 :
795:2010/05/10(月) 01:51:59
素早い回答有り難う御座いました。
Cの勉強初めて数日の者ですが質問です
#include<stdio.h>
main(){
char a,b;
scanf("%c",&a);
printf("%c",a);
scanf("%c",&b);
printf("%c",b);
return 0;
}
これを実効すると
一つ目の文字を入力した時点で終了してしまうのですが何故でしょうか?