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

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

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

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

Q&A

解決済

3回答

1925閲覧

ファイルを削除する関数で行き詰まっています。

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2018/01/04 14:11

編集2018/01/06 05:49

できました。皆さんありがとございます。
次にdata_tel.txtにdata_tmpをコピーしてこのdelete()
関数を完成したいと思います。また
ご教授ください。よろしくお願いいたします。
data_tel.txt
sachiko ,090-0809
naka ,090-7777
kiyoko ,090-9999
satou ,090-3214
kinosita ,090-8769
yamada ,090-4325
itou ,080-6354
sudou ,090-3333
kitou ,080-13424

コード // data_kirikae8.c #include <stdio.h> #include <string.h> #include <stdlib.h> //for exit #include <sys\stat.h> #define Max 100 char dtfile[]="data_tel.txt"; char dtfile2[]="data_tmp.txt"; int main(void) { FILE *fp1,*fp2 ; char line[Max]={0}; // 検索対象文字列を読み込む配列 char line2[Max]={0}; char buff[256]; //検索文字列 int count=0; char *ptr; if(!(fp1 = fopen(dtfile, "r"))){ printf("ファイルを開くことができません\n"); return -1; } if ((fp2 = fopen(dtfile2, "r+")) == NULL) { fprintf(stderr, "ファイルのオープンに失敗しました.\n"); return -1; } printf("削除する名前を検索します。検索する名前を入力して下さい。\n"); scanf("%s",buff); //linesから1行ずつ取り出す。 while(fgets(line, 256, fp1) != NULL){ printf( "line=%s" ,line ); ptr=strstr(line,buff); if(ptr){ continue; }else{ // 書き込み fputs(line,fp2); count++; if ( count < 0 ) { count=fprintf(stderr, "ファイルの書込みに失敗しました.\n"); return -1; } } fclose(fp2); } fp2 = fopen(dtfile2, "r"); printf("\n\n"); while(fgets(line2, 256, fp2) != NULL){ printf( "line2=%s",line2); } // ファイルクローズ fclose(fp2); fclose(fp1); } /*【実行結果例】 naka@naka ~/kadai/kadai9-8 $ gcc -o data_kakikae8 data_kakikae8.c -Wall naka@naka ~/kadai/kadai9-8 $ data_kakikae8 削除する名前を検索します。検索する名前を入力して下さい。 naka line=sachiko ,090-0809 line=naka ,090-7777 line=kiyoko ,090-9999 line=satou ,090-3214 line=kinosita ,090-8769 line=yamada ,090-4325 line=itou ,080-6354 line=sudou ,090-3333 line=kitou ,080-1342 line2=sachiko ,090-0809 line2=kiyoko ,090-9999 line2=satou ,090-3214 line2=kinosita ,090-8769 line2=yamada ,090-4325 line2=itou ,080-6354 line2=sudou ,090-3333 line2=kitou ,080-1342 naka@naka ~/kadai/kadai9-8 $ naka@naka ~/kadai/kadai9-8 $

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

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

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

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

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

otn

2018/01/04 15:03

質問のポイントは何ですか?
退会済みユーザー

退会済みユーザー

2018/01/04 15:09

5項目目の具体的なコードの書き方が分からないです。
otn

2018/01/04 15:16

①ファイルの編集の仕方、②削除とリネームの仕方、の2つの質問と言うことですか?
退会済みユーザー

退会済みユーザー

2018/01/04 15:22

分かりにくい質問ですみません。5.のような仕様で、コードを書きたいのですが、ファイルの編集の仕方がわかりません。指針でもいいのでお願いいたします。
Zuishin

2018/01/04 15:27

余計な事かもしれませんが、C は車で言えばマニュアル車に似ています。ハンドルもアクセルもブレーキもクラッチも人に任せてウィンカーだけ操作するくらいならオートマ車を練習した方が上達します。
guest

回答3

0

こんにちは。

かなり混乱しているように見えます。
char lines[MAX}[40];のような変数を定義して、そこへ1行ずつfgetsで全部読み込み、次にlinesから1行ずつ取り出しながら、指定文字列が含まれていないならファイルへ書き込めば良いのではないでしょうか?

投稿2018/01/05 19:13

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2018/01/06 00:43

久しぶりです。ご助言ありがとうございます。ヨタヨタしながらここまでできました、やってみます。
yumetodo

2018/01/06 03:38

あれっ、そういえばこれ改行の保証ある入力を仮定していいのかな
退会済みユーザー

退会済みユーザー

2018/01/06 04:31

yumetodoさんおはようございます。1個だけコピーされていて、そこでとまるみたいです。 1回正常にnakaが削除されてdata_tmp.txtにほかのデータがコピーされたのですが、端末にdata_tmp.txtが表示されないので、修正するうち肝心のdata_tmp.txtにうまくコピー出来なくなりました。 コードのしたの方のfp2 = fopen(dtfile2, "r");からしたをあちこちに挿入してそうなったと思うのですが、よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2018/01/06 05:53

Chironianさん出来ました。ありがとございます。これからもよろしくお願いいたします。
guest

0

https://teratail.com/questions/105239
の続きですかね・・・。

strstrで削除したい文字列の位置を探せると思うんですが、削除したい文字列の先頭の一つ前の位置をfwriteに渡せば、削除する文字列の直前までを別ファイルに書き出せますよね?そして再び削除したい文字列の直後からstrstrで探す。

イメージとしては

c

1const char* input_str = /*ファイルから読み込んだ全文字列の先頭へのポインタ*/; 2const char* search_str = /*検索文字列*/; 3const size_t search_str_len = strlen(search_str); 4const File* tmp_file_handle = fopen(/*なんか*/, "wb"); 5//頑張る 6const char* delete_str_front = NULL; 7for( 8 const char* p = input_str; 9 NULL != (delete_str_front = strstr(input_str, search_str)); 10 p = delete_str_front + search_str_len 11){ 12 fwrite(tmp_file_handle, p, delete_str_front - p); 13}

こんな感じ?(もっとちゃんとエラー対策して)

ところで元の回答作っておいてなんだけれども、removeしたファイルと同名のファイル名にrenameできる保証ってあるのかな・・・

やっぱりこういうプログラムって書くべきじゃないなと思う。

投稿2018/01/05 03:12

編集2018/01/05 03:19
yumetodo

総合スコア5850

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

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

退会済みユーザー

退会済みユーザー

2018/01/05 03:44

私もそういう気がしてきました。しかしc言語のことが大分勉強になりました。途中で諦めるとc言語の勉強も諦めそうで怖いです。趣味が無くなりそうで。ボケ防止です。色々教えて頂いて感謝いたします。それでは頑張ってみます。
guest

0

ベストアンサー

まず、元ファイルから1行読み込んで、別ファイルに1行書き出す処理を考えましょう。
これを元ファイルから読み込めなくなるまで回せばファイルのコピーができますね。
あとは1行書き出す直前に行に削除する名前が含まれているかチェックする処理を挟むだけです。

追記3
以下の行をループの外に出して下さい。クローズするのは書き込みが全部終わった後です。

fclose(fp2);

以下の部分ですが、先にi++してしまうと、line[i]には値が入っていません。
そもそも、マッチする値が見つかった場合は、fp2に出力する必要はありません。

i++;
fputs(line[i],fp2);

また、1行ずつ読み込んで処理しているので、line[i],line2[i]は毎回使い捨てになります。
Max個用意する必要はありません。ここを整理すると変数iも必要なくなるのでソースがかなりスッキリします。

char line[Max][40]={0};
char line2[Max][40]={0};

投稿2018/01/04 15:26

編集2018/01/06 04:51
hichon

総合スコア5737

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

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

退会済みユーザー

退会済みユーザー

2018/01/05 03:08

ありがとうございます。ファイルから読みかきを勉強しなおしています。
hichon

2018/01/06 04:39

追記しました。
hichon

2018/01/06 04:52 編集

ごちゃごちゃしてきたので、追記3にまとめました。
退会済みユーザー

退会済みユーザー

2018/01/06 05:51

hichonさん出来ました。ありがとございます。これからもよろしくお願いいたします。
episteme

2018/01/06 06:01

質問を書き直しちゃダメだ。流れが掴めんじゃないか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問