2011-08-07 4 views
2

で最後の改行を削除します。は、私は次の関数から最後の改行を削除するC

void WriteToFile(node *tree) 
{ 
    void Write(node*); 
    fp = fopen("dictionary.txt","w"); 
    if(fp==NULL) 
    { 
     printf("Cannot open file for writing data..."); 
    } 
    else //if(tree==NULL) 
    { 
     if(tree!=NULL) 
     { 
      Write(tree); 
     } 
     fclose(fp); 
    } 
} 
void Write(node *tree) 
{ 
    if(tree!=NULL) 
    { 
     fprintf(fp,"%s:%s\n",tree->word,tree->meaning); 
     Write(tree->left); 
     Write(tree->right); 
    } 
} 

私はBSTの内容をテキストファイルに書き込むように、この機能を使用しています、と私はいけません最後の改行を書いてほしいですが、どうすれば削除できますか?

+1

私は好奇心が強いです。最後の行に改行を書いてみませんか?従来、テキストファイルのすべての行は、最後の行を含めて改行で終了する必要がありました。 –

答えて

5

あなたのような再帰ルーチンでは、最後の呼び出しは簡単にわかりませんが、最初の呼び出しが分かります。

のではなく、必要に応じて、改行をデータを書き込むと、データに続いて、オプションの改行書いて考えてみます。

void FirstWrite(node *tree, FILE *fp) 
{ 
    if (tree) 
    { 
     fprintf(fp, "%s%s", tree->word, tree->meaning); 
     Write(tree->left, fp); 
     Write(tree->right, fp); 
    } 
} 
void Write(node *tree, FILE *fp) 
{ 
    if (tree) 
    { 
     fprintf(fp, "\n%s%s", tree->word, tree->meaning); 
     Write(tree->left, fp); 
     Write(tree->right, fp); 
    } 
} 

をしかし、テキストモードのファイルのためのラインの最も使用される定義を考えるには、次のとおりです。シーケンスの0文字以上の改行があり、改行を含む。この定義によると、すべて行に改行があります。ファイル内の最後のデータは行ではありません。

私が使った悪い書き方のプログラムの少なくとも1つは、そのために入力全体を処理できません。私の推測では、それが

fgets(buf, sizeof buf, inf); 
inlen = strlen(buf); 
if (buf[inlen - 1] == '\n') processline(buf); 

データの最後のピースは、改行が含まれている場合、このひどく書かれたプログラムはうまくいくような何かをするということです。

1

ツリー全体を書き込んだ後、ファイルを1バイトで切り捨てることができます。 How to truncate a file in Cこちらを参考にしてください。

通常、最終ノード\ にあることを知って最後の\ nを書き込もうとすることはできますが、このツリーの実装を考慮すると、コードにほとんど変更を加える必要がないため、アプローチがより速くなるかもしれません。 - これを行う方法のサンプルは、Oli Charlesworthによって与えられています。このアプローチは、より良いと思っています(修正するのではなく、害を及ぼさない)。

void Write(node *tree, int isFarRight) 
{ 
    if(tree!=NULL) 
    { 
     fprintf(fp,"%s:%s",tree->word,tree->meaning); 
     if (!isFarRight || tree->left || tree->right) 
     { 
      fprintf(fp, "\n"); 
     } 
     Write(tree->left, 0); 
     Write(tree->right, isFarRight); 
    } 
} 

... 

Write(tree, 1); 

isFarRight変数を使用すると、ツリーの一番右側に現在しているかどうかを追跡します:次のように

+0

私はこれを確認します.. – Caffeinatedwolf

3

は、あなたの関数を変更します。現在のノードに子がある場合、または右端にない場合は、'\n'のみを表示します。

+0

はい、あなたは正しいです、私はそれを取得します。 – Caffeinatedwolf

3

すでにファイルに書き込まれたら、サイズにファイルを切り詰めるためにftruncateのを使用することができます - _chsize代わりにftruncateの

_chsize(fd, size - 1); 
+0

+1しばしばやりすぎて元に戻すのは簡単です。 –

+0

答えは、これはPOSIX準拠のシステムでのみ機能することを指摘しておきます。 –

+0

ありがとうOli、私は私の答えを修正しました –

1

あなたは可能性の使用、Windows上で1

size_t size = ftell(fp); 
ftruncate(fp, size - 1); 

あなたのメインで

void Write(node *tree, int first) { 
    if (tree!=NULL) { 
    if (!first) 
     fprintf(fp, "\n"); 
    fprintf(fp,"%s:%s",tree->word,tree->meaning); 
    Write(tree->left, 0); 
    Write(tree->right, 0); 
    } 
} 

、コールWrite(tree, 1);:このようにそれを行います。きれいではありませんが、動作するはずです。

+0

私はそれをよりきれいにするための最初の(= 1)のデフォルト値を持つことをお勧めしたいと思います。呼び出し側は、Write –

+2

@Armenの実装の詳細を気にするべきではありません: –

+0

それは素晴らしいですが、2番目の関数が必要です - 私はあなたができるようにCのデフォルト値を持つことはできないと思いますC++。 [pmg](http://stackoverflow.com/users/25324/pmg)そのようなものを投稿しました。 – Mat

0

これはツリーを左から右に順に印刷しますか?

私は次のように再帰的な書き込みツリーが定義されるべきだと思う:

write(tree *node) 
{ 
    write(node->left); 
    printf(.....); 
    write(node->right); 
} 

は、あなたの関数が順にツリーを印刷していることを確認していますか?

0

あなたのコードでは、ツリーのルートのテキストがNULLであることに注意してください。したがって、関数定義を変更することなく:

void WriteToFile(node *tree) 
{ 
    void Write(node*); 
    fp = fopen("dictionary.txt","w"); 
    if(fp==NULL) 
    { 
    printf("Cannot open file for writing data..."); 
    } 
    else //if(tree==NULL) 
    { 
    if(tree!=NULL) 
    { 
     fprintf(fp,"%s:%s",tree->word,tree->meaning); 
     Write(tree); 
    } 
    fclose(fp); 
    } 
} 
void Write(node *tree) 
{ 
    if (tree->left) 
    { 
    fprintf(fp,"\n%s:%s",tree->left->word,tree->left->meaning); 
    Write(tree->left); 
    } 

    if (tree->right) 
    { 
    fprintf(fp,"\n%s:%s",tree->right->word,tree->right->meaning); 
    Write(tree->right); 
    } 
} 
関連する問題