以下のデータを削除する関数を作りたいのですが、
void data_delete()のコードの不備、誤りを教えてください。
とりあえずここまでできています。
void data_delete()でデータを削除するコードが分かりません。
/*これはdata_telというファイルを操作するプログラムでいいのかな?
削除の実装は標準Cだけだとかなりだるい。
別ファイルに書き出して元ファイル削除してリネームという手法になる。
ファイル削除はremove、ファイル名変更はrenameを使う。
つまり
現状のコード同様文字列検索する。
1. 一つでも見つかったらfstatでファイルサイズを求める
2. ファイルサイズ分のメモリーを確保
3.fseekでファイル先頭に戻り、freadですべて確保したメモリーへ読み込み。
一時ファイルのハンドルを得る
4.strstrを駆使しながら削除部分以外を一時ファイルにfwriteで書き込み(大変)
全ファイルハンドルclose
5.data_telをremove
6.一時ファイルをdata_telにrename
というくっそ面倒なことやることになる。
data_amend()
*/
/* data_tel
naka 080-7777
kiyoko 090-9999
satou 090-3214
kinosita 080-8679
yamada 090-4325
*/
#include<stdio.h>
#include<string.h> //for strcmp,strstr
#include<stdlib.h> //for exit
#define N 256
#define MAX 100 // MAX100人
char names[MAX][20]; // MAX100人、20文字
char tel[MAX][20]; // MAX100人、20文字
int val; // 名前と番号の配列番号
void data_show(); // データ表示
void data_delete();
int main()
{
data_delete();
data_show();
}
void data_show()
{
FILE *fp;
val=0;
if(!(fp = fopen("data_tel.txt", "r"))){
printf("ファイルを開くことができません\n");
exit(1);
}
printf("名前番号\n");
printf("-------------------------\n");
while(fscanf(fp, "%s%s", names[val], tel[val])!=-1)
{
printf("%-10s%5s\n",names[val], tel[val]);
val++;
}
fclose(fp);
}
void data_delete() {
static char buff[N];
FILE *fp;
int len;
int i=0;
val=0;
if(!(fp = fopen("data_tel.txt", "r"))){
printf("ファイルを開くことができません\n");
exit(1);
}
printf("削除する名前を検索します。検索する名前を入力して下さい。\n");
scanf("%s",buff);
while(fscanf(fp, "%s%s", names[val], tel[val])!=-1){
//fscanfでファイルを1行ずつ読み込む
// while( fscanf(fp,"%s,%s",&buf[0],&buf[1]) != EOF ){
// printf("%s,%s\n",buf[0],buf[1]);
if(strstr(names[val],buff) || strstr(tel[val],buff)){
//文字列namesの中から文字列buffを探しそのアドレスを返す。
//発見できなければNULL(\0)を返す。
printf("%-10s%5s\n",names[val],tel[val]);
i=1;
len = strlen( &names[100][20]);
// 文字列namesの長さを返す。
// strlen関数は文字列の長さを「バイト数」で返します。
// namesの長さは20バイト, telの長さは20バイト,\0がついているので
// データ1行の長さは42バイト
printf( "len=%d\n" , len );
//見つかると削除する(ここで削除したい)
}
}
printf("削除された名前: %s\n", buff);
if(i==0)
printf("名前が見つかりません: %s\n", buff);
fclose(fp);
}
/*実行結果
naka@naka ~/kadai
$ gcc -o data_delete1 data_delete1.c -Wall
naka@naka ~/kadai
$ data_delete1
削除する名前を検索します。検索する名前を入力して下さい。
kiyoko //関数scanfの表示
kiyoko 090-9999 //関数data_delete1の表示
len=4
削除された名前: kiyoko
名前番号 //関数data_show();の表示
-------------------------
naka 080-7777
kiyoko 090-9999
satou 090-3214
kinosita 080-8679
yamada 090-4325
naka@naka ~/kadai
*/
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
これはdata_tel
というファイルを操作するプログラムでいいのかな?内容的に素直にSQL(MariaDBとかとか)使って、という思いがあるけどそれはさておき。
data_delete()
肝心の削除部分がない。
削除の実装は標準Cだけだとかなりだるい。
別ファイルに書き出して元ファイル削除してリネームという手法になる。
ファイル削除はremove
、ファイル名変更はrename
を使う。
つまり
- 現状のコード同様文字列検索する。
- 一つでも見つかったら
fstat
でファイルサイズを求める - ファイルサイズ分のメモリーを確保
fseek
でファイル先頭に戻り、fread
ですべて確保したメモリーへ読み込み。- 一時ファイルのハンドルを得る
strstr
を駆使しながら削除部分以外を一時ファイルにfwrite
で書き込み(大変)- 全ファイルハンドルclose
data_tel
をremove
- 一時ファイルを
data_tel
にrename
というくっそ面倒なことやることになる。
data_amend()
上記同様。やはりだるい。
結論
難易度高すぎるので素直にSQLつかいません?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 91.04%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
Zuishin
2017/12/20 10:32
C の学習のためにやっているのなら頑張ってください。実用なら awk を使うと多分一行で書けます。