int main(void){
....
while(!(i==EOF)){
num=0;
while((i=fgetc(stream))!='\n'){
if(i==EOF) break;
str[num]=i;
num++;
}
kannsuu1();
kannsuu2();
}
return 0;
void kannsuu1(void){
printf("出力されない");
for(i=0;str[i]!=NULL;i=i+2){
printf("%c%c",str[i],str[i+1]);/*これも出力されない*/
}
}
void kannsuu2(void){
....
}
簡単に上記のように記述したプログラムがあるのですが、コンパイラの警告はまったくかかりませんでしたが、関数の中のprintfがdosプロンプトに出力されないのですよ。だれか心あたりがありましたらおしえてもらえないでしょうか?
お願いいたします。
No.8
- 回答日時:
うーん、、、Nickeeさんのソース丸々コピーして、divide()とcall_di()だけコメントにして実行したら、ちゃんと動きましたよ?(全角SPは消しましたが…)
OSはWin98、コンパイラはBorland C/C++ 5.5です。
↓これが使用したテストデータです。
あいうえお\n
さしすEOF
↓これが実行結果です。(DOS窓よりコピーしました)
ここからあいうえお
ここからさしす
・Nickeeさんの方の実行結果の画面って、どうなってます?できたらDOS窓のコピーをお願いします。
・とりあえずresult()以外の2つの関数呼び出しをコメントにして、↑のような超単純データでテストしてみてもらえますか?
・またresult()の代わりにputs(str)を実行してみてもらえますか?
#要求ばかり多くてゴメンなさい。。
以上、よろしくお願いします。
?????????????????????????????
( ? 0 ? )
なんか、いわれたとおりに、コメントにしたら、出力ができて、コメントを消してもう一度実行したら、プログラムが動きました。ちょっと、markの位置が微妙にづれていましたが。。。
うーーん?なぜ?
putsもうごきました。
とりあえず、直ったのでいいのですが、とりあえず、これで、締め切りたいのですが、leaz024さんにこれまで、付き合ってもらって、一方的に切るのは悪いと思いましたので、leaz024さんのご意見を聞かせてもらってから、切ろうと思います。
もし、なかったら、"ない"でもよろしいので。
ちなみに、僕は、原因がわかりません。メモリとか、関係あるんですかね。。
No.7
- 回答日時:
コンパイルでエラーが出たということですが、もしかしてNo.5のサンプルから、コピーしたりしました?
サンプルはブラウザでの見栄えをよくするために、半角スペースやタブを使うところを「全角スペース」で書いています。文字列内などでない場所で全角文字を使用すると、「無効な文字がありました」のようなエラーになります。
お使いのテキストエディタに「全角スペースを何らかの記号で表示する機能」などがあれば、有効にしておく便利ですよ。
またソース全体を選択し、「全角スペース→半角スペース2個」の置換を実行してみるとよいでしょう。
#もし上記が見当違いの回答だとしたら、次の補足をお願いします。
>rewindを使用したら、コンパイルエラーがでて
このときに追加したコードを、そのまま見せていただけますか?
>rewindだけをけして
とは、どのようなことをされたのでしょうか?
この回答への補足
どうやら、コンパイラエラーは全角スペースが原因だったようです。leaz024さんのいうとおり、コピーをしてはりつけてしまいましたから。。
まだ、rewindをsetvbufをつかっても出力されないんですよ。もう、お手上げです。
下記にソースプログラムをのせておくので、leaz024さんもお忙しいと思われるので、暇で、気が向いた時でよろしいのですので、目を通してもらえれば、幸いです。結構長いので。。。
ちなみに、このプログラムは、あるテキストからdictionary.txtにある文字を探して、その部分だけ、||で囲もうとしたものです。文字はすべて、全角をいう設定で。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int mark[100];
char str[200];
char com[10][200][20];
char moji[100];
void divide(void);
void call_di(void);
void compare(char *moji);
void result(void);
/*======================================================================*/
int main(int argc,char *argv[]){
FILE *stream;
int i=0,k,num;
for(i=0;i<=99;i++) mark[i]=0;
setvbuf(stdout,NULL,_IONBF,0);
if(argc!=2) {
printf("使用法:<プログラム名><ファイル名>\n");
exit(1);
}
if((stream=fopen(argv[1], "r"))==NULL){
printf("can't open\n");
exit(1);
}
while(!(i==EOF)){
num=0;
while((i=fgetc(stream))!='\n'){
if(i==EOF) break;
str[num]=i;
num++;
}
str[num]=NULL;
str[num+1]=NULL;
divide();
call_di();
result();
printf("\n");
}
fclose(stream);
return 0;
}
/*======================================================================*/
void divide(void){
int k,num,m;
for(k=1;k<11;k++){
for(num=0;num<strlen(str)/2;num++){
for(m=0;m<k*2;m++){
com[k][num][m]=str[num*2+m];
}
com[k][num][m+1]='\0';
}
}
}
/*======================================================================*/
void call_di(void){
FILE *stream2;
int i,num=0;
if((stream2=fopen("dictionary.txt","r"))==NULL){
printf("can't_open_error\n");
exit(1);
}
while((i=fgetc(stream2))!=EOF){
moji[num]=i;
if(moji[num]=='\n') {
moji[num]=NULL;
num=-1;
compare(moji);
}
num++;
}
fclose(stream2);
}
/*======================================================================*/
void compare(char *moji){
int i;
for(i=0;i<strlen(str)/2;i++){
if(strcmp(moji,com[strlen(moji)/2][i])==0){
mark[i]=1;
mark[strlen(moji)/2+i]=1;
}
}
}
/*======================================================================*/
void result(void){
int i;
/*ここからの出力ができない*/
printf("ここから");
for(i=0;str[i]!='\0';i=i+2){
printf("%c%c",str[i],str[i+1]);
if(mark[i/2]) printf(" | ");
}
rewind(stdout);
}
No.6
- 回答日時:
>>memset(str, '\0', strlen(str)); /* これしないと、まずくない? */
>これは文字列の最後にNULLをいれるということでしょうか?いちおう、単純にstr[n]=NULL;ってしてあります.
例には書いてないだけで、他の雑用的な処理はなされているのですね。もしかしたら、その延長で処理してあるのかも知れませんが、一応気になったので・・・
str[n] = NULL;
これって、main関数内の処理の方にあるってことですよね?
kansuu1内では、strの中を1個おきにしか調べていないので、奇数番目にヌルが入っていると、そのままループが継続されてしまう可能性があります。
(前回の入力よりも入力した文字数が少なく、文字列長が奇数の場合)
kansuu1の処理が3個単位になっても、1個単位になってもOKなように、2個のヌルを入れるのではなく、memsetでクリアするようにしてみました。
それからヌルの使い方なんですが、ヌルを表すNULLと'\0'には
・NULL … 無効ポインタ
・'\0' … 文字列の終端記号
という、意味の違いがあります。
(Cでは
#define NULL ((void *)0)
という処理系もあるので、この場合は'\0'とは全くの別物です。)
使ってしまえばどちらも0なので問題はないのですが、人にソースを公開する場合には解読の助けにもなるので、このような使い分けは大事ですよ。
(特に集団開発などでは、人のコードを読まされる場合なんて多々あります。)
この回答への補足
すいません何度も。。
rewindを使用したら、コンパイルエラーがでて、
不正な文字 'character' (0x'value')
入力ファイルの中に無効な文字がありました。
その文字の 16 進値が出力されます。
これは,関数マクロに余分な引数が渡されたことが原因であることもあります。
.....なんて警告がでてしまい、しまったとおもって、rewindだけをけして、もう一度コンパイルしたら、この警告が消えなくなってしまいました。何か思い当たるふしがあるようであれば、もう一度アドバイスを願いたいのですが。。
No.5
- 回答日時:
そもそもコンパイラの警告やエラーというのは
・プログラム自体が間違っている場合
(セミコロン抜けや括弧の不整合、文法ミスなど)
・間違いではないが、プログラマのミスではないかと思われるような記述を見つけた場合
(ifやwhileなどの条件式内で、代入のみが行われているなど)
などに発せられるもので、動作の不具合を教えてくれるものではありません。
(このような実行時の不具合を一般に「バグ」と呼びます。バグを警告してくれるコンパイラなんてあったら、世の中つまんなくなっちゃうでしょ?)
で本題ですが、a-kumaさんがおっしゃられているように、printf関数の出力先である「標準出力(stdout)」は、デフォルトでバッファリングを行うように設定されています。
バッファリング付き出力先に対して出力を行う際は、バッファが満タンになるか、改行('\n')が出力されるかまで、実際の出力は行われません。
途中途中で改行してやるのがベターなのですが、スクロールできないDOS窓プログラムなので、大量の情報を表示するために改行をしていないのでしょう。
こういう場合、バッファリングを切ったりするのも手なんですが、バッファリングを切らずに、しかも改行しないで出力を実行させる関数があります。
【書式】
#include <stdio.h>
void rewind(FILE *fp);
この関数を使えば、その時点でバッファの中身が出力先デバイスに送られます。
引数には、<stdio.h>内で定義されているstdoutを指定すればOKです。
例のリストは少し見にくかったので、少々手直しをしたサンプルを載せておきます。
#include <stdio.h>
#include <string.h>
/* main()内部 */
:
do {
n = fgetc(stream);
if (n != EOF && n != '\n') {
str[num++] = (char)n;
} else {
kannsuu1();
kannsuu2();
num = 0;
memset(str, '\0', strlen(str)); /* これしないと、まずくない? */
}
} while (n != EOF);
:
/* kansuu1()内部 */
:
printf("表示されない?");
for (i = 0; str[i] != NULL; i += 2) {
printf("%c%c", str[i], str[i+1]);
}
rewind(stdout); /* この関数実行後、画面に出力される */
:
とりあえずはrewindの行を追加するだけでも動きますので、お試しください。
この回答への補足
memset(str, '\0', strlen(str)); /* これしないと、まずくない? */
これは文字列の最後にNULLをいれるということでしょうか?いちおう、単純にstr[n]=NULL;ってしてあります.
とりあえず,rewindをつかってみます。ありがとうございました。
No.4
- 回答日時:
まず、コンパイル環境くらいは書きましょう。
32bit Windowsなら「Win32コンソール」アプリ
ケーションにすればprintfの出力が見れます。
「関数のプロトタイプ宣言」が先であることは
分かっていますよね。
それと、
while(!(i==EOF)){
num=0;
while((i=fgetc(stream))!='\n'){
の使い方はあまり感心しません。
通常File I/Oでは
while((i=fgetc(stream))!=EOF){
//必要な処理を書く
}
の様に書くのが普通ではないでしょうか?
今回のケースだと、
num=0;
while((i=fgetc(stream))!=EOF){
if(i=='\n'){
kannsuu1();
kannsuu2();
num=0;
//ここでstr[]の中身をpaddingする必要がある
}
else{
str[num]=(char)i;
num++;
}
}
if(num>0){//これがないと最後の1行が処理されない
kannsuu1();
kannsuu2();
}
の様になるでしょう。
この回答への補足
コンパイルの環境って。うーん、よくわかりませんけど、OSはwin98でBorlandの
TurboC++をインストールしています。
関数のプロトタイプ宣言もちゃんとしています。
>while(!(i==EOF)){
num=0;
while((i=fgetc(stream))!='\n'){
の使い方はあまり感心しません。
通常File I/Oでは
while((i=fgetc(stream))!=EOF){
//必要な処理を書く
}
の様に書くのが普通ではないでしょうか?
いや、一行づつ処理をしたかったので。。。
>今回のケースだと、
num=0;
while((i=fgetc(stream))!=EOF){
if(i=='\n'){
kannsuu1();
kannsuu2();
num=0;
//ここでstr[]の中身をpaddingする必要がある
}
else{
str[num]=(char)i;
num++;
}
}
if(num>0){//これがないと最後の1行が処理されない
kannsuu1();
kannsuu2();
}
うーーーん、プログラムの処理のしかたが違っているような気がする。。
参考にさせてもらいます。ありがとうございました。
No.3
- 回答日時:
int main(void){
....
while(!(i==EOF)){
while((i=fgetc(stream))!='\n'){
if(i==EOF) break;
}
kannsuu1();
}
return 0;
}
void kannsuu1(void)
{
printf("出力されない");
}
勝手にまとめさせてもらうとこんなプログラムになりますが
これで”出力されない”が出力されないなら
素人の私では回答できません。
もしよかったら
このプログラムがどのように終了するのか
教えてください。
int main(void){
....
while(!(i==EOF)){
while((i=fgetc(stream))!='\n'){
if(i==EOF) break;
}
kannsuu1();
}
fclose(stream);
return 0;
}
void kannsuu1(void)
{
printf("出力されない");
}
って具合で同じなのですけれど、勉強不足のため、どのようにプログラムが終了するかっていうのが、わからないのですけども。
たとえを書いてもらえるわかるのですが。
No.2
- 回答日時:
「出力されない」というのは、その関数を呼び出したタイミングで、ということ
なのでしょうね。
printf() は、普通、出力をバッファリング、つまり、関数の中で一時貯めておきます。
その貯めた中身を吐き出す、つまり、出力するのは、バッファが一杯になるか、改行(\n)に
当たったときです。
「dosプロンプトに」とあるので、勝手に Visual C/C++ だと想像しますが、関数の
リファレンスに書いてあります。
これを避けるためには、方法はふたつ。
ひとつは、バッファリングされていない stderr を使うこと。printf() を
fprintf(stderr, ...) に置き換えます。
もうひとつは、setvbuf() 関数を使って、バッファリングをしない指定をすること。
stdout に対して、バッファリングしない指定 _IONBF を指定します。
詳細は、関数のリファレンスを見て欲しいのですが、多分こんな感じの関数呼び出しを
最初に一発だけしておけば良いです。
setvbuf(stdout, NULL, _IONBF, 0);
バッファリングをしない指定なので、バッファのアドレスやそのサイズは、
NULL と 0 を指定しておけば良いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PS4コントローラーをPCでゲーム...
-
4Kの外部モニターに出力すると...
-
AIに回答させるって
-
プログラムについての質問です...
-
COBOLのMOVEで桁数が異なる場合
-
VBAで出力したCSVファイルの先...
-
TV出力ポートをOFFにすれば良い...
-
printfとputcharの違いは
-
スマホのバッテリー消費につい...
-
ACCESS クエリ→フォーム...
-
テキストファイルから特定の文...
-
【UNIX】echoコマンドのタブが...
-
VBAのExecメソッドで画面を非表...
-
LaTeX:tableofcontentsによる目...
-
シェルスクリプト初心者です。#...
-
誘導電動機の機械出力はPoです...
-
coutで出力した文字を消去する...
-
KEYENCEのシーケンスプログラム...
-
プリンタ出力
-
Excel VBAで値を変えながら、pd...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PS4コントローラーをPCでゲーム...
-
4Kの外部モニターに出力すると...
-
プログラムについての質問です...
-
MMDでavi出力が出来ない
-
COBOLのMOVEで桁数が異なる場合
-
cout と cerrの違い
-
printfとputcharの違いは
-
アクセスでエクセルに出力する...
-
VBAのExecメソッドで画面を非表...
-
スマホのバッテリー消費につい...
-
Windows Formアプリからコンソ...
-
ACCESS クエリ→フォーム...
-
コンセントの電力は入力と出力...
-
Accessのテーブルからcsv出力す...
-
Excel VBAで値を変えながら、pd...
-
無線とかアンテナに関しの質問...
-
ListViewの複数選択について
-
KEYENCEのシーケンスプログラム...
-
センサーのタンパー出力について
-
VBAでテキスト出力時のスペース...
おすすめ情報