質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

無限ループが発生してしまう

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,176

score 560

現在、Cの練習も兼ねてアセンブラを作っていました。
そこで気になったバグ?を見つけ、なぜそのようになるのかわかりません。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FILE_OPEN_ERROR 1
#define FILE_WRITE_ERROR 2
#define MEMORY_OVER_ERROR 3

/* バッファサイズは0未満にならないのでunsigned */
typedef unsigned int size_i;

typedef char BYTE;
typedef unsigned char UBYTE;
typedef short WORD;
typedef unsigned short UWORD;
typedef int DWORD;
typedef unsigned int UDWORD;
typedef long QWORD;
typedef unsigned long UQWORD;

typedef struct
{
    char *buf;
    size_i bs;        /* now buffer size / buffer seek pos */
    size_i mbs;        /* max buffer size */
} BUFFER;

void buffer_w(BUFFER *buf, BYTE data);
int buffer_tofile(FILE *fw, BUFFER *buf);

int main(int argc, char **argv)
{
    char *inf = argv[1], *outf = argv[2];
    fprintf(stdout,"in:%s out:%s\n", inf, outf);

    FILE *fr = fopen(inf, "r");
    if(fr == NULL){
        fprintf(stderr,"input file open error.\n");
        return FILE_OPEN_ERROR;
    }else{
        char buf[256];
        /* 改行文字も入れて読み込む */
        fgets(buf,255,fr);
        while(buf != NULL){
            /* 改行文字をはじめの位置から探す */
            char *end = strchr(buf,'\n');
            /* 見つかった場合改行文字を終端文字に置き換え */
            /*if(end != NULL)*/ end[0] = 0;
            fprintf(stdout,"read:%s\\\n", buf);
            /* buffer clear */
            fgets(buf,255,fr);
        }
    }
    fclose(fr);

    fprintf(stdout,"buffer allocate\n");
    /* バッファの最大サイズ */
    size_i buffer_size = 512;
    /* 書き込み用バッファ */
    BUFFER *buff = (BUFFER *)malloc(sizeof(BUFFER));
    if(buff == NULL) return MEMORY_OVER_ERROR;
    buff->buf = calloc(1, buffer_size);
    if(buff->buf == NULL) return MEMORY_OVER_ERROR;
    buff->bs = 0;
    buff->mbs = buffer_size;

    /* テスト */
    fprintf(stdout,"buffer write test.\n");
    buffer_w(buff, 0x90);
    buffer_w(buff, 0xfa);
    buffer_w(buff, 0xfb);

    FILE *fw = fopen(outf, "wb");
    if(fw == NULL){
        fprintf(stderr,"output file open error.\n");
        return FILE_OPEN_ERROR;
    }else{
        int a = buffer_tofile(fw, buff);
        if(a != 0){
            switch(a){
                case FILE_WRITE_ERROR:{
                    fprintf(stderr,"output file can't write data.");
                    break;
                }
            }
        }
    }
    fclose(fw);

    return 0;
}

/* バッファに1バイト書き込む */
void buffer_w(BUFFER *buf, BYTE data)
{
    if(buf->bs == buf->mbs){
        /* バッファがすべて埋まったので何もしない */
        return;        /* buffer max */
    }else{
        buf->buf[buf->bs] = data;
        buf->bs++;
    }

    return;
}

/*
 * バッファのデータをファイルに書き込む
 * 書き込むバイトがない場合何もしない
 *
 * return:
 * 0:正常終了
 * それ以外:例外終了 原因はマクロと同じ
 */
int buffer_tofile(FILE *fw, BUFFER *buf)
{
    if(fw == NULL) return FILE_OPEN_ERROR;

    if(buf->bs > 0){
        int a = fwrite(buf->buf, buf->bs, 1, fw);
        if(a < 1) return FILE_WRITE_ERROR;
    }

    return 0;
}


strchr関数を呼んだあと、もし見つからなかったらNULLが帰るようになっているそうなので、if文を使ってNULLでない場合は処理を行う、というようにしました。しかし、その後コンパイルして実行すると、今回の読み込んだファイルでは今回の読み込んだファイルでは3行目が無限にループしてしまいました。

読み込んだファイル

NOP
CLI
STI

環境は、windows、gccを使用しています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+2

まず、私はコード読んでいません。
こういうのはコードを読むより、デバッグしたほうが早いです。

MinGW辺りならGDB、VC++なら内蔵のデバッガ、
その両方でも使えるprintfデバッグ法でデバッグします。

参考: エラーの取り除き方

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

なんかちょっとコードを見ていると、コードがひどいですね

        while(buf != NULL){

このwhile ループ、無限ループになってますね。
まあ、その他にも明らかなバグがいくらか散見されます

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

while(buf != NULL){
bufは配列先頭アドレスなので、絶対にNULLではないです。

「ファイルを終わりまで読んだら」ということなら、fgetsの返り値を見ます。

        char buf[256];
        /* 改行文字も入れて読み込む */
        while(fgets(buf,255,fr)){
            /* 改行文字をはじめの位置から探す */
            char *end = strchr(buf,'\n');
            /* 見つかった場合改行文字を終端文字に置き換え */
            /*if(end != NULL)*/ end[0] = 0;
            fprintf(stdout,"read:%s\n", buf);
        }


ただ、同じ変数に上書きし続けると、結局最後の行しか取れないので、これでは駄目。
全体構造がおかしいので、ゼロから作り直した方が良いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

一応バグはなくなりました。

/*if(end != NULL)*/ end[0] = 0;```  

if(end == 0) break;  
end[0] = 0  


にしました。
なぜこのようになったのかはわかりません。
また、すこしコードをいじって調べたらわかったので、BeatStarさんをベストアンサーにしたいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る