• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:続jファイルに文字列を書く)

続jファイルに文字列を書く方法とエラーの解決方法

このQ&Aのポイント
  • チャットのシステム作成において、読み込み時にエラーが発生しています。ソースコードの注目部分を見てください。
  • 注目部分のバグを修正する方法を教えてください。
  • ファイルに書き込む際の注意点なども教えていただけると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.5

>+1を入れると\0がはいるんじゃないんですか? strlen()は「引数で渡されたアドレスから」文字列終端までの長さを返します。 '\0'が入る領域を用意するのであれば、「strlen()の返した値」に+1する必要があります。 ですので、"123456789"と9文字入っているアドレスの"2"が入っているところから数えたら8文字しかありませんよね? 掲示されたコードは"2"から数え始めてね。と指定しているのです。 # そして、"2"からコピーしてね。としてコピーしています。 >fp= fopen("now.txt","r"); >while( fgets( buf, 400, fp ) != NULL ){ >tm[0]=(char*)malloc(strlen(buf)+1); >strcpy(tm[0], buf); >} では、正しく「文字数+1」となっているのに、問題の箇所では「先頭2文字目からの文字数」となっているのはなぜですか? >つまりstrcpy(tm[i], buf+3); >にすれば何とかなるのですね そりゃエラーにはならないかも知れませんが、それが想定している動作なんですか? 掲示されたファイルの例(Shift-JIS想定)だと…… 1回目で(3行目がヘンになっているかも知れない。半角カナになっている為) ---moto.txt--- 激塔W (空行) ゥん 2回目の実行で ---moto.txt--- ジ (空行) (空行) (空行) になりますかね。 # 3行目が空行かゴミが出るかは状況次第のギャンブル。 >想定外と申されましても試行錯誤して書き換えているので想定そのものができません では期待動作はなんなんでしょうか?

nanaka2223
質問者

お礼

って私が書いたプログラムをわざわざ修正して2回できるようにしたのですね お手数おかけして申し訳ありません このままコメントがなければベストアンサーにさせえていただきますね

nanaka2223
質問者

補足

>>>+1を入れると\0がはいるんじゃないんですか? strlen()は「引数で渡されたアドレスから」文字列終端までの長さを返します。 '\0'が入る領域を用意するのであれば、「strlen()の返した値」に+1する必要があります。 あ、そういえばそうですね 勘違いしてました +1入れろと書いてあったので間違えたようです >>ですので、"123456789"と9文字入っているアドレスの"2"が入っているところから数えたら8文字しかありませんよね? 掲示されたコードは"2"から数え始めてね。と指定しているのです。 # そして、"2"からコピーしてね。としてコピーしています。 ポインターの位置換えですね だから1行目が消えたのですね >fp= fopen("now.txt","r"); >while( fgets( buf, 400, fp ) != NULL ){ >tm[0]=(char*)malloc(strlen(buf)+1); >strcpy(tm[0], buf); >} では、正しく「文字数+1」となっているのに、問題の箇所では「先頭2文字目からの文字数」となっているのはなぜですか? 見落としてかいたのか試行錯誤しているうちに偶然に書き換えてしまったからです 指摘していただきありがとうございます。 >つまりstrcpy(tm[i], buf+3); >にすれば何とかなるのですね <<そりゃエラーにはならないかも知れませんが、それが想定している動作なんですか? 掲示されたファイルの例(Shift-JIS想定)だと…… 1回目で(3行目がヘンになっているかも知れない。半角カナになっている為) ---moto.txt--- 激塔W (空行) ゥん 2回目の実行で ---moto.txt--- ジ (空行) (空行) (空行) になりますかね。 # 3行目が空行かゴミが出るかは状況次第のギャンブル。 想定の意味が自分が思ったようにこうしたいと言う理想の処理と言う意味であれば 想定外ですよ 申し訳ありませんね 想定の意味がプログラムを書き換えた後で必ずこうなる事を知っている事が想定と言う意味だと勘違いしていました >想定外と申されましても試行錯誤して書き換えているので想定そのものができません >>では期待動作はなんなんでしょうか? 期待している動作 1回目の動作で もも みかん オレンジ をmoto.txtの内容にする 2回目の動作で追加したい文字がぶどうなら ぶどう もも みかん オレンジ をmoto.txtの内容にする 3回目の動作で追加したい文字がいちごなら いちご ぶどう もも みかん オレンジ をmoto.txtの内容にする 期待している動作はこんな感じです

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.4

>再三指摘されているfgets()での改行コードに 失礼しました。 再三指摘されていたのは別人でした。 たぶんお友達だと思いますけど。

nanaka2223
質問者

お礼

よく見たらNO2~5さんまでWr5さんでしたね いつもお世話になってありがとうございます また変な事を聞いていたらすみませんね 今までのおかげでだいぶチャットが完成まじかになりましたよ 機能もいろいろ増えましたしね。 最もミニゲームも加える予定なのでチャットができたら完成って訳ではないんですけどね 今までは一人用のチャットを作れるようにしていたのですが 複数人いた時用のプログラムに以降予定です ここまでアドバイスしていただき本当にありがとうございました

nanaka2223
質問者

補足

nanaka2222の事でしたら私自身ですよ 間違えてログアウトしたらパスワードを覚えていなくて戻れなくなりましてnanaka2223jを新たに作りました ちなみに私に友達はいません

すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.3

>ちゃんと動作するにはどのように書けば良いですか? どういう動作が期待している動作なのか? が不明です。 とりあえず、問題にしている箇所でバッファオーバーランを発生させないようにするのであれば、 tm[i] = (char*)malloc(strlen(buf+1)); strcpy(tm[i], buf+1); は tm[i] = (char*)malloc(strlen(buf)); // buf文字分しかないけど次のコピーで1文字カットするから'\0'の分はある。 strcpy(tm[i], buf+1); とすべきでしょう。 まあ、これで読み込んだ行の先頭1文字を削除できるか?は、ファイル次第ですけど。 Shift-JISなテキストファイルで1文字目に日本語とか書かれていたら…ヘンになるかも知れませんし、 ASCIIで記述されたテキストファイルならたぶん正しく1文字目が削除されるでしょう。 # 現状のmoto.txtだとたぶん壊れます。 再三指摘されているfgets()での改行コードに関しては…まぁ、問題ないのでしょう。 私的には気持ち悪い処理内容ですが……。 # 部下や教えている生徒がこういうコード書いてきたら、なぜそうなるのかキチンと説明を求めるレベル。 「1行目の次に空行を挿入して、それ以降の行は空行を挿入しない処理です。」以外の回答があるのかは謎。

nanaka2223
質問者

補足

期待している動作 1回目の動作で もも みかん オレンジ をmoto.txtの内容にする 2回目の動作で追加したい文字がぶどうなら ぶどう もも みかん オレンジ をmoto.txtの内容にする 3回目の動作で追加したい文字がいちごなら いちご ぶどう もも みかん オレンジ をmoto.txtの内容にする 期待している動作はこんな感じです <<まあ、これで読み込んだ行の先頭1文字を削除できるか?は、ファイル次第ですけど。 Shift-JISなテキストファイルで1文字目に日本語とか書かれていたら…ヘンになるかも知れませんし、 ASCIIで記述されたテキストファイルならたぶん正しく1文字目が削除されるでしょう。 # 現状のmoto.txtだとたぶん壊れます。 逆です1文字目が消えちゃうからバグなのです 一文字も消えずにそのまま表示したいのです <<再三指摘されているfgets()での改行コードに関しては…まぁ、問題ないのでしょう。 それは修正しましたよ <<私的には気持ち悪い処理内容ですが……。 私から見れば順番に処理画家かれてるので見やすいですが、他の方が同様のプログラムを作る場合なんて全くないのでどうして気持ち悪いのかわかりません。ごめんなさい。 ただ他の人の書いたソースは見ずらいと言うことでしたら私も同様にみづらいなと思うこともあるのでお互いさまなのではないでしょうか? <<# 部下や教えている生徒がこういうコード書いてきたら、なぜそうなるのかキチンと説明を求めるレベルなぜそうなるのかと言われましても順番に処理を書いていってバグなどがおきたり新しい処理を追加していったらいつの間にか自然とそうなったとしか、後はそのため試行錯誤を繰り返したらそうなったとしかいえません <<「1行目の次に空行を挿入して、それ以降の行は空行を挿入しない処理です。」以外の回答があるのかは謎 そういう風に答えれば良いんですね でしたら最初の一行目は一度別のファイルに文字列をすべて書き込んで文字列をつなげた一つの文字列にしました その理由は漢字、ひらがな、#等の文字をstrcatで連結させようとするとめちゃくちゃバグるからです そのっため別のファイルに書き込んだ文章を再び呼び出してtm[0]に格納しました その次にmoto.txtにかかれた文字列を順次tm[i]に格納して文字列をつなげて表示したかったのですがバグが発生しました 3行目で最初の文字が消えるだけでなく、4行目を書き込もうとしたらエラーになる そのため試行錯誤してバグを取り除こうとした結果、最初の一文字つつきえるとはいえチャットのように何行も書き込める方法を発見ちょっと喜びました その後バグがなくなるよう試行錯誤したのですが発見できずこちらで相談させていただきました このような回答でよろしいでしょうか?

すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

malloc()のバグではなく、「使い方」の問題でしょう。 今時malloc()にバグが潜在するようなライブラリなんてないでしょうし。 >tm[i] = (char*)malloc(strlen(buf+1)); の意図ってなんでしょう? なぜ「bufのアドレスに+1」する必要があるんですか? 文字列終端の'\0'の分が確保されませんから、次の >strcpy(tm[i], buf+1); //ここを注目 で、『予定通り』バッファオーバーランを実行します。 # tm[i] = (char*)malloc(strlen(buf)+1); # だったら、「bufに入っている文字列をコピーするのに必要なサイズ」が確保されますけど… # 掲示されたコードでは「bufに入っている文字列を2文字少なくコピーできるサイズ」しかありません。 バッファオーバーランで想定外の箇所を書き換えているのですから… >文字列が1文字ずつ消えていく >3行目を書き込んだ時点で3行目がの頭の部分の文字列がおかしくなり4行目を書き込もうとするとエラー という動作になっても想定内のハズです。

nanaka2223
質問者

補足

>>tm[i] = (char*)malloc(strlen(buf+1)); の意図ってなんでしょう? なぜ「bufのアドレスに+1」する必要があるんですか? 文字列終端の'\0'の分が確保されませんから、次の >strcpy(tm[i], buf+1); //ここを注目 で、『予定通り』バッファオーバーランを実行します。 +1を入れると\0がはいるんじゃないんですか? # 掲示されたコードでは「bufに入っている文字列を2文字少なくコピーできるサイズ」しかありません。 つまりstrcpy(tm[i], buf+3); にすれば何とかなるのですね <バッファオーバーランで想定外の箇所を書き換えているのですから… <という動作になっても想定内のハズです。 想定外と申されましても試行錯誤して書き換えているので想定そのものができません

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

他のところと見比べればわかっていいはずなんだが.... 「malloc して strcpy」する関数を, なぜ作らない?

nanaka2223
質問者

補足

そういう関数が必要ですか? うまくできるようあたまっをひねって見ます

すると、全ての回答が全文表示されます。
このQ&Aのポイント
  • 電圧・電力が異なるため、台湾製モーターを国内で使用するには対策が必要です。
  • 日本の電力環境に合わせるためには、変圧器を使用する必要があります。
  • 安全に使用するためには、国内の規格に合わせた配線や接地を行う必要があります。
回答を見る

専門家に質問してみよう