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プロンプトに出力されないのですよ。だれか心あたりがありましたらおしえてもらえないでしょうか?
お願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (9件)

出力できるようになったのですね?ヨカッタヨカッタ!



原因が分からない事なんて多々あります(笑)
そのうち原因に気が付くこともあるしね。

とりあえずmarkの位置修正などでソースとのにらめっこなどが続くと思います。
頑張ってください。
    • good
    • 0
この回答へのお礼

どうも今までありがとうございました。

お礼日時:2001/05/08 14:26

 うーん、、、Nickeeさんのソース丸々コピーして、divide()とcall_di()だけコメントにして実行したら、ちゃんと動きましたよ?(全角SPは消しましたが…)



OSはWin98、コンパイラはBorland C/C++ 5.5です。

↓これが使用したテストデータです。
あいうえお\n
さしすEOF

↓これが実行結果です。(DOS窓よりコピーしました)
ここからあいうえお
ここからさしす

・Nickeeさんの方の実行結果の画面って、どうなってます?できたらDOS窓のコピーをお願いします。
・とりあえずresult()以外の2つの関数呼び出しをコメントにして、↑のような超単純データでテストしてみてもらえますか?
・またresult()の代わりにputs(str)を実行してみてもらえますか?

#要求ばかり多くてゴメンなさい。。

以上、よろしくお願いします。
    • good
    • 0
この回答へのお礼

?????????????????????????????
( ? 0 ? )
なんか、いわれたとおりに、コメントにしたら、出力ができて、コメントを消してもう一度実行したら、プログラムが動きました。ちょっと、markの位置が微妙にづれていましたが。。。
うーーん?なぜ?
putsもうごきました。
とりあえず、直ったのでいいのですが、とりあえず、これで、締め切りたいのですが、leaz024さんにこれまで、付き合ってもらって、一方的に切るのは悪いと思いましたので、leaz024さんのご意見を聞かせてもらってから、切ろうと思います。
もし、なかったら、"ない"でもよろしいので。
ちなみに、僕は、原因がわかりません。メモリとか、関係あるんですかね。。

お礼日時:2001/05/08 10:03

 コンパイルでエラーが出たということですが、もしかして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);
}

補足日時:2001/05/06 13:09
    • good
    • 0

>>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だけをけして、もう一度コンパイルしたら、この警告が消えなくなってしまいました。何か思い当たるふしがあるようであれば、もう一度アドバイスを願いたいのですが。。

補足日時:2001/05/05 19:24
    • good
    • 0

 そもそもコンパイラの警告やエラーというのは


  ・プログラム自体が間違っている場合
   (セミコロン抜けや括弧の不整合、文法ミスなど)
  ・間違いではないが、プログラマのミスではないかと思われるような記述を見つけた場合
   (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をつかってみます。ありがとうございました。

補足日時:2001/05/05 14:00
    • good
    • 0

まず、コンパイル環境くらいは書きましょう。


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();
 }
うーーーん、プログラムの処理のしかたが違っているような気がする。。

参考にさせてもらいます。ありがとうございました。

補足日時:2001/05/05 13:45
    • good
    • 0

int main(void){


....
  while(!(i==EOF)){
    while((i=fgetc(stream))!='\n'){
      if(i==EOF) break;
    }
    kannsuu1();
  }
  return 0;


void kannsuu1(void)
{
  printf("出力されない");



勝手にまとめさせてもらうとこんなプログラムになりますが
これで”出力されない”が出力されないなら
素人の私では回答できません。

もしよかったら
このプログラムがどのように終了するのか
教えてください。
    • good
    • 0
この回答へのお礼

int main(void){
....
  while(!(i==EOF)){
    while((i=fgetc(stream))!='\n'){
      if(i==EOF) break;
    }
    kannsuu1();
  }
  fclose(stream); 
  return 0;


void kannsuu1(void)
{
  printf("出力されない");


って具合で同じなのですけれど、勉強不足のため、どのようにプログラムが終了するかっていうのが、わからないのですけども。
 たとえを書いてもらえるわかるのですが。

お礼日時:2001/05/05 13:43

「出力されない」というのは、その関数を呼び出したタイミングで、ということ


なのでしょうね。

printf() は、普通、出力をバッファリング、つまり、関数の中で一時貯めておきます。
その貯めた中身を吐き出す、つまり、出力するのは、バッファが一杯になるか、改行(\n)に
当たったときです。

「dosプロンプトに」とあるので、勝手に Visual C/C++ だと想像しますが、関数の
リファレンスに書いてあります。

これを避けるためには、方法はふたつ。

ひとつは、バッファリングされていない stderr を使うこと。printf() を
fprintf(stderr, ...) に置き換えます。

もうひとつは、setvbuf() 関数を使って、バッファリングをしない指定をすること。
stdout に対して、バッファリングしない指定 _IONBF を指定します。

詳細は、関数のリファレンスを見て欲しいのですが、多分こんな感じの関数呼び出しを
最初に一発だけしておけば良いです。

  setvbuf(stdout, NULL, _IONBF, 0);

バッファリングをしない指定なので、バッファのアドレスやそのサイズは、
NULL と 0 を指定しておけば良いです。
    • good
    • 0
この回答へのお礼

 うーーん、わからない、何をいっているのか。。まあ、一行ずつ解読しつつ、読み進めていきます。ありがとうございました。

お礼日時:2001/05/05 14:06

printfの中に\nの改行マークを入れてないというのはどうでしょうか?


古い、unixならためておくこともあると思います。

あと、13行目のreturnの後ろに}で閉じてないのは、
省略しているだけですよね。
    • good
    • 0
この回答へのお礼

windowsなので、13行目はわすれていました。参考にさせてもらいます。ありがとうございました。

お礼日時:2001/05/05 13:38

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

QC言語のプログラムが実行できません。

C言語のプログラムが実行できません。

コンパイルは出来るんですが、実行すると、「Segmentation fault」と表示されてしまいます。

これは何のエラーなんでしょうか?
基本的な事かもしれませんが、分かる方宜しくお願い致します。

Aベストアンサー

僕も何度も出したなぁ。

ひとくちにSegmentation faultといっても、それこそさまざまな要因があるので、
これだけで原因を突き止めるのは非常に難しいです。

コンパイルはあくまで文法としてみているだけであり、
処理の流れ、メモリ確保など、プログラムそのものを見ているわけではありません。
このエラーが出るのは文法などよりもっと上位の原因なのです。
たとえばですが。
長さ10の配列があったとして、11番目以降を参照したりすると、
そういうのが出たような気がします。

ですから、変数があれば、その内容をprintf文で逐一出していき、
変な値が入っていないとか、少しずつ直していくしかないと思います。

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Qprintf による16進表示について

C言語初心者です。

今作っているプログラムで、データを16進形式で表示しようとしています。
大体このような感じです。

/*入力時*/
char buf[5]={0x4e,0x94,0xa0,0x2b,0x78}

/*出力時*/
for (i = 0; i < 5; i++) {
printf("0x%02x\n",buf[i])
}

実際には入力後にある処理によってbufは更新されるのですが、printfの出力結果として、

0xffffff4e
0x94
0xffffffa0
0x2b
0x78

というように、'ffffff'が付加したものがいくつか出力されてしまいます。
これはどういった意味を持つのでしょうか?

なんか初心者ならではの漠然とした質問ですいません。。。

Aベストアンサー

出力は、
0x4e
0xffffff94
0xffffffa0
0x2b
0x78
ではありませんか?
char が符号付(-128~127)のため、0x80~0xffは負の数とみなされます。printfの引数になる時に 符号付charは符号付intに変換されますが、このCコンパイラの場合は、int が4バイトcharが1バイトのため、上位3バイトに負の数を示すffffffが入ります。
char x=255;
printf("%d\n",x);
だと255でなく、-1が表示されます。

対応としては、
unsingned char buf[5]={0x4e,0x94,0xa0,0x2b,0x78}
;
とするか、
printf("0x%02x\n",buf[i]&0xff);
にするかどちらかですね。

QEnterキーを押されたら次の処理に移るという事をしたい。

コンソールアプリケーション上で文字列を表示させた後、ユーザーがエンターキーを押したら次の文字列を表示するという仕様にしたいのですが、エンターキーだけ入力待ちにするっていうのはどのように書けばいいんでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void)
{
char *str[] = {"abc", "def", "ghi", "jkl"};
int i;

for(i = 0; i < 4; i ++){
while(getchar() != '\n') ;
puts(str[i]);
}
return 0;
}

Qprintfだと出力されるのにfprintfだと出力されないのはなぜですか?

今プログラムを作りかけなのですが、
forで何回もまわして計算しているので
printfでそのまま出力すると見づらくなってきたので
テキストに出力したくてちょっといじってみたんですが、テキストは作成されるんですが肝心の数字が出力されていません。

ソースのいじったところは
pritf("s[%d]=%f\n",a,b);
となっていたところを

メイン分の最初で
FILE *fp;
を宣言して

fp=fopen("test.txt","w");
省略
fpritf(fp,"s[%d]=%f\n",a,b);

と直しただけなのですが
test.txtに何も書き込まれません。
ソースを省略しすぎかもしれませんが
よろしくおねがいします。

Aベストアンサー

fcloseしてからtest.txtの中身を確認してますか?

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

QC言語 While文(ループ)内の文字入力

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }

   return 0;
}

【実行結果(キーボードからは「 e 」と入力」)】
1文字を入力:e
入力したのは e です。
1文字を入力:入力したのは
です。
1文字を入力:

【私が意図している結果】
1文字を入力:e
入力したのは e です。
1文字を入力:


 ちなみにC言語の環境は、インターネットで無料で入手できる試食版です。(LSI C-86 Ver3.30c 試食版)
 上記プログラムを見てもらえればお分かりだと思いますが、「xを入力するまで、永遠と1文字入力とその表示を行う」ことを意図しています。しかし実際の結果は意図に反しています。
 1回目は正常に動作しているようですが、問題は2回目以降。scnafで入力待ちをすることなく、なぜかscanfをスルーする形で3回目のscanf入力待ちとなっています。この理由を教えてください。お願いします。

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == ...続きを読む

Aベストアンサー

>1文字を入力:入力したのは
>です。

は、[Enter]キーの入力によるためです。
[Enter]キーをスルーする必要があります。

   char a;
char dummy; /*[Enter]キー用*/

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);
scanf("%c",&dummy); /*[Enter]キー用*/

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }


で、どうでしょうか?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング