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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

1167閲覧

ループ2回目以降が上手くいきません。ファイルの入出力 strtok_s関数

madanai

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2020/07/30 12:20

編集2020/07/31 00:37

アドレス帳のような機能を作っています。

不具合が起きているのは、profile_edit関数「mail.txtのデータ(元のデータ)をmail2.txtに書き写しながら、変更したい部分に新しい文字列を挿入する」のところです。
今の状態だと「元の文字列が消えずに残っているが表示されない」ので1回目のループはうまくいきます。
2回目以降だと、消えずに残っている文字列が邪魔をしてうまくいきません。1回目のループで、元の文字列を上書きもしくは削除したいです。

使う関数自体変えればいいのでしょうが、知識が浅くどの関数をどう使えばいいのか分からない状態です。(strtok_s関数とCSVファイルを使うとうまくいくのかなと考え程度です)

専門用語等分からないことが多いです。

よろしくお願い致します。

C言語

1 2#include <stdio.h> 3#include <string.h> 4 5int profile_edit ( int , char [ 256 ] ); 6 7struct profile { /* プロフィール構造体 */ 8 char name [ 256 ]; /* 氏名 */ 9 char code [ 256 ]; /* 郵便番号 */ 10 char add [ 256 ]; /* 住所 */ 11 char tel [ 256 ]; /* 電話番号 */ 12 char mail [ 256 ]; /* メールアドレス */ 13}; 14FILE* fp; 15FILE* fp2; 16 17int main ( ) 18{ 19 struct profile prof; 20 char file_in [ 256 ]; 21 int num = 0; 22 int end = 0; 23 24 printf ( "【アドレス帳】\n" ); 25 do { 26 printf ( "\nアドレスの\n\t[登録]:1\t[編集]:2\n\t[削除]:3\t[参照]:4\t数字を入力:" ); 27 scanf_s ( "%d" , &num ); 28 printf ( "\n" ); 29 if ( num == 1 ) { /* 1の場合 */ 30 fopen_s ( &fp , "mail.txt" , "w" ); 31 if ( fp == NULL ) { 32 return 0; 33 } 34 printf ( "氏名     :" ); 35 scanf_s ( "%s" , prof.name , 255 ); 36 printf ( "郵便番号   :" ); 37 scanf_s ( "%s" , prof.code , 255 ); 38 printf ( "住所     :" ); 39 scanf_s ( "%s" , prof.add , 255 ); 40 printf ( "電話番号   :" ); 41 scanf_s ( "%s" , prof.tel , 255 ); 42 printf ( "E-mailアドレス:" ); 43 scanf_s ( "%s" , prof.mail , 255 ); 44 fputs ( "氏名     :" , fp ); 45 fputs ( prof.name , fp ); 46 fputs ( "\n郵便番号   :" , fp ); 47 fputs ( prof.code , fp ); 48 fputs ( "\n住所     :" , fp ); 49 fputs ( prof.add , fp ); 50 fputs ( "\n電話番号   :" , fp ); 51 fputs ( prof.tel , fp ); 52 fputs ( "\nE-mailアドレス:" , fp ); 53 fputs ( prof.mail , fp ); 54 fputs ( "\n" , fp ); 55 fclose ( fp ); 56 } 57 else if ( num == 2 ) { /* 2の場合 */ 58 fopen_s ( &fp2 , "mail2.txt" , "w" ); 59 if ( fp2 == NULL ) { 60 printf ( "編集ができません。\n" ); 61 break; 62 } 63 fopen_s ( &fp , "mail.txt" , "r" ); 64 if ( fp == NULL ) { 65 printf ( "連絡先が見つかりません。\n" ); 66 break; 67 } 68 int edit = 0; /* 編集番号を受け取る */ 69 int a = 0; /* profile_edit関数の引数を受け取る */ 70 char newdata [ 256 ]; 71 printf ( "どの項目を編集しますか?\n\t[氏名]:1\t[郵便番号]:2\n\t[住所]:3\t[電話番号]:4\n\t[E-mailアドレス]:5\t\t数字を入力:" ); 72 scanf_s ( "%d" , &edit ); 73 printf ( "\n新しい情報を入力してください。\n\t:" ); 74 scanf_s ( "%s" , newdata , 255 ); 75 76 profile_edit ( edit , newdata ); 77 if ( a = profile_edit ( edit , newdata ) == 0 ) { 78 printf ( "新しい情報に書き換えられました。\n" ); 79 } 80 else { 81 printf ( "編集に失敗しました。\n" ); 82 break; 83 } 84 } 85 86 else if ( num == 3 ) { /* 3の場合 */ 87 88 if ( remove ( "mail.txt" ) == 0 ) { 89 printf ( "連絡先を削除しました。\n" ); 90 } 91 else { 92 printf ( "連絡先の削除に失敗しました。\n" ); 93 } 94 } 95 else if ( num == 4 ) { /* 4の場合 */ 96 fopen_s ( &fp , "mail.txt" , "r" ); 97 if ( fp == NULL ) { 98 printf ( "連絡先が見つかりません。\n" ); 99 do { 100 printf ( "\n続けますか?[はい]:1 [いいえ]:2\t数字を入力:" ); 101 scanf_s ( "%d" , &end ); 102 } while ( ( end != 1 ) && ( end != 2 ) ); 103 if ( end == 2 ) { 104 return 0; 105 } 106 else { 107 continue; 108 } 109 } 110 while ( 1 ) { 111 fgets ( file_in , 255 , fp ); 112 if ( feof ( fp ) ) { 113 break; 114 } 115 printf ( "%s" , file_in ); 116 } 117 fclose ( fp ); 118 } 119 else { 120 printf ( "1~4の数字を入力し直してください。\n" ); 121 continue; 122 } 123 124 do { 125 printf ( "\n続けますか?[はい]:1 [いいえ]:2\t数字を入力:" ); 126 scanf_s ( "%d" , &end ); 127 } while ( ( end != 1 ) && ( end != 2 ) ); 128 if ( end == 2 ) { 129 break; 130 } 131 } while ( end == 1 ); 132 133 return 0; 134} 135 136// 関数名 : profile_edit 137//テキストファイルの1部を書き換える関数 138int profile_edit ( int row , char str [ 256 ] ) 139{ 140 int ch = 0; 141 int nr = 0; 142 int nc = 0; 143 144 while ( ( ch = fgetc ( fp ) ) != EOF ) { 145 fputc ( ch , fp2 ); 146 if ( ch == '\n' ) { 147 nr++; 148 } 149 if ( nr == row - 1 ) { 150 nc++; 151 } 152 if ( nc == 17 ) { 153 fputs ( str , fp2 ); 154 fputc ( '\n' , fp2 ); 155 fputc ( '\0' , fp2 ); 156 157 nr++; 158 nc++; 159 } 160 } 161 fclose ( fp ); 162 fclose ( fp2 ); 163 164 fopen_s ( &fp2 , "mail2.txt" , "r" ); 165 if ( fp2 == NULL ) { 166 return -1; 167 } 168 fopen_s ( &fp , "mail.txt" , "w" ); 169 if ( fp == NULL ) { 170 return -1; 171 } 172 while ( ( ch = fgetc ( fp2 ) ) != EOF ) { 173 fputc ( ch , fp ); 174 } 175 fclose ( fp ); 176 fclose ( fp2 ); 177 178 return 0; 179} 180

Visuai studio

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/07/30 12:58

提示のコードにはどういう不具合があって、それをどうしたいんでしょうか。 そこらへん詳しく説明しましょう。 いきなりコード出されても読む気にもなりません
madanai

2020/07/31 00:27

失礼しました。 不具合が起きているのは、profile_edit関数「mail.txtのデータ(元のデータ)をmail2.txtに書き写しながら、変更したい部分に新しい文字列を挿入する」のところです。 今の状態だと「元の文字列が消えずに残っているが表示されない」ので1回目のループはうまくいきます。 2回目以降だと、消えずに残っている文字列が邪魔をしてうまくいきません。1回目のループで、元の文字列を上書きもしくは削除したいのです。 使う関数自体変えればいいのでしょうが、知識が浅くどの関数をどう使えばいいのか分からない状態です。(strtok_s関数とscvファイルを使うとうまくいくのかなと考え程度です)
y_waiwai

2020/07/31 00:30

それを質問に追記しましょう。 修正依頼に書いてても読まれません
guest

回答2

0

自己解決

C

1fopen_s ( &fp2 , "mail2.txt" , "r" ); 2 if ( fp2 == NULL ) { 3 return -1; 4 } 5 fopen_s ( &fp , "mail.txt" , "w" ); 6 if ( fp == NULL ) { 7 return -1; 8 } 9 while ( 1 ) { 10 fgets ( file_in , 255 , fp2 ); 11 if ( feof ( fp2 ) ) { 12 break; 13 } 14 fputs ( file_in , fp ); 15} 16fclose ( fp ); 17fclose ( fp2 );

投稿2020/07/31 02:52

編集2020/07/31 02:53
madanai

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1回目の編集で、mail.txtから目的の項目を変更してmail2.txtを作ってそのまま(作りっぱなし)ですよね?
これでは2回目の編集は何も変わっていないmail.txtから読み上げてmail2.txtを作り直すので1回目の編集内容が元に戻ってしまいます。
編集が終わって、ファイルをクローズしたら、
0. mail.txtを削除する。
0. mail2.txtをmail.txtにリネームする。
が必要です。

strtok_sとCSVを使用したい理由は、想像ですがアドレス帳(mail.txt)の各項目をカンマ区切りで格納して、編集の際カンマで区切ったトークンとして項目を扱いたいのかな?

投稿2020/07/30 22:48

DreamTheater

総合スコア1095

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

madanai

2020/07/31 00:30

mail2.txtはデータを一時保管しているだけで、最後にmail.txtにすべて上書きしています。 不具合が起きているのは、profile_edit関数「mail.txtのデータ(元のデータ)をmail2.txtに書き写しながら、変更したい部分に新しい文字列を挿入する」のところです。 新しい文字列を元の文字列に上書き、もしくは新しい文字列を挿入した後に元の文字列を削除したいです。 そのためには、データ(文字列)ごとに配列に格納するのがいいと思い、strtok_sで区切りCSVファイルを作成するのが手っ取り早いかな、と思ったのです。知識はありません。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問