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

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

ただいまの
回答率

91.04%

  • C

    2968questions

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

名前と番号のデータを削除する関数を作りたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 152

sanchu52

score 101

以下のデータを削除する関数を作りたいのですが、
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2017/12/20 10:32

    C の学習のためにやっているのなら頑張ってください。実用なら awk を使うと多分一行で書けます。

    キャンセル

回答 1

checkベストアンサー

+1

これはdata_telというファイルを操作するプログラムでいいのかな?内容的に素直にSQL(MariaDBとかとか)使って、という思いがあるけどそれはさておき。

 data_delete()

肝心の削除部分がない。

削除の実装は標準Cだけだとかなりだるい。
別ファイルに書き出して元ファイル削除してリネームという手法になる。

ファイル削除はremove、ファイル名変更はrenameを使う。

つまり

  1. 現状のコード同様文字列検索する。
  2. 一つでも見つかったらfstatでファイルサイズを求める
  3. ファイルサイズ分のメモリーを確保
  4. fseekでファイル先頭に戻り、freadですべて確保したメモリーへ読み込み。
  5. 一時ファイルのハンドルを得る
  6. strstrを駆使しながら削除部分以外を一時ファイルにfwriteで書き込み(大変)
  7. 全ファイルハンドルclose
  8. data_telremove
  9. 一時ファイルをdata_telrename

というくっそ面倒なことやることになる。

 data_amend()

上記同様。やはりだるい。

 結論

難易度高すぎるので素直にSQLつかいません?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/18 05:57

    色々、この方法では面倒そうですね。拾って来たプログラムですけど、そんなんで削除と修正がないのだと思います。関数の勉強のためにすこしがんばってやってみます。途中で放棄するかもしれませんが、ありがとうございます。分からないときはまたおねがいいたします。

    キャンセル

  • 2017/12/18 09:21

    引き続きこの質問にリプライしていただくかTwitter/mastodon(@yumetodo@pawoo.net)にリプライいただければ見に行きます

    キャンセル

  • 2017/12/18 15:51

    ありがとうございます。お仕事がありますので少し時間をください。リストを使ったプログラムは
    なんとか読み解いたのですが、ご教授頂いたコメントの関数を勉強したいとおもいます。

    キャンセル

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

  • ただいまの回答率 91.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    2968questions

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