• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ランダムアクセスファイルでファイルの一部削除)

ランダムアクセスファイルでファイルの一部削除

このQ&Aのポイント
  • (UNIXのgccでUDP使ってネットワーキングしてるんですが) ログアウトしたユーザーの名前をファイルから削除する方法は?
  • ランダムアクセスファイルでログアウトしたユーザーの名前を削除する方法について教えてください。
  • ファイルからログアウトしたユーザーの名前を削除する方法を教えてください。

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

>strcpy(record_file.userID, ""); しておくくらいでいいんじゃないですかね。 そうすれば、ファイル上はゴミデータが残っていても、 >readUserID(id); で読み出せないワケですからログインしているユーザーにはなりませんよね。 なんだったら、'\0'でパディングすればいいかと思います。 通常こういう処理では、一部のデータを本当に削除しようと思ったら、データ全体の移動が起こってしまいますから、こうした削除マークを付けておくだけにして、余裕があるときに、バキュームするというかバッチ的にファイルの更新をする時にレコードを削除すればいいと思います。

kicker
質問者

お礼

答えて下さってたんですね。 質問後にチェックしたんですが何故かしばらく回答なしでした。 実はもう自分なりに考えて解決したのですが '\0'でパディングする方法は知っておくべきでした。 ""だけだとそのゴミデータ自身がまだ古いIDのままなので 検索すると見つかってしまいましたので。 でも、削除って面倒なんですねぇ。 ファイルの更新時に要るデータだけ移すのは良い案ですね。 大変勉強になりした。 ありがとうございました。

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

関連するQ&A

  • TCP/IP: 非ソケットに対するソケット操作です?

    UNIX/gcc。 TCP/IPでチャットプログラムを作っているんですが ログアウトメッセージなるものを送る前に sendto() sent a different number of bytes than expected: Socket operation on non-socketというエラーが出ます。 起こる箇所:クライアント msgStruct.option = htonl(option); msgStruct.seatLog = htonl(loggedIn); if (sendto(sock, &msgStruct, sizeof(msgStruct), 0, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) != sizeof(msgStruct)) { printf("sizeof(msgStruct): %d\n", sizeof(msgStruct)); DieWithError("sendto() sent a different number of bytes than expected"); これはどういうときに起こるのでしょうか? このエラーが起こり始めたのはファイルの中のポート番号の値を変えてからです。 元通りにポート番号をコマンドの引数から得た値に直せば このエラーは消えますが、そうするとチャットプログラムとして動作しなくなってしまいます。 //これで各自のクライアントが独自のポート番号を持てます echoDummyAddr.sin_port = 29990 + (unsigned short)recordNumber; //元々はechoServPort = atoi(argv[1]);で得た値を送ってました loggedIn = logIn(option, msgString, seatLog, inet_ntoa(echoClntAddr.sin_addr), echoDummyAddr.sin_port); 関数側(端折ってます): int logIn(int option, char *id, int loggedIn, char *ip, unsigned short portNum) { FILE *file_ptr; user record_file; record_file.portNum = portNum; fwrite(&record_file, sizeof(record_file), 1, file_ptr); fclose(file_ptr); } return loggedIn; } 小さなヒントでもいいですから、どうか宜しくお願いします。

  • ファイルの内容の表示

    実行時のコマンドライン引数で指定したファイルの内容を、行番号付きで画面に表示するプログラムを作る という問題です。ヒントも与えられています。 行番号付きの表示、コマンドライン引数の利用。両者を組み合わせればできるはずだ >  main関数の引数にargcとargvを指定して、コマンドライン引数をファイル名として利用する。キーボード入力を促す文(プロンプト)や改行チェックは不要なので書かないこと >  コマンドライン引数が指定されない場合は、メッセージを表示してプログラムを終了 >  ファイルの内容を画面表示する処理は、ユーザー定義関数put_file_contentsに記述する。仮引数には文字型のポインタ変数をひとつ指定し、ファイル名を受け渡せるようにする。put_file_contents自体の型は整数型(int)で、正常終了なら返り値0を返すこと。 行番号付きのプログラム#include<stdio.h> > int put_file(char *filename); > > int main() > { > char line[50]; > char *ptr; > > printf("ファイル名を入力:"); > fgets(line,sizeof(line),stdin); > ptr = line + strlen(line) - 1; > if(*ptr == '\n') { > *ptr = '\0'; > } > > put_file(line); > > return 0; > } > > int put_file(char *filename) > { > FILE *fp; > char buf[100]; > int line_no; > > fp = fopen(filename,"r"); > if (fp == NULL){ > printf("%sを開けません\n",filename); > return 1; > } > line_no = 1; > while (fgets(buf,sizeof(buf),fp) != NULL){ > printf("%3d: ",line_no); > printf("%s",buf); > line_no++; > } > fclose(fp); > > return 0; > } で、コマンドライン引数のプログラムは#include<stdio.h> void write_key_inputs(char *filiname); int main(int argc, char *argv[1]) { write_key_inputs(argv[1]); return 0; } void write_key_inputs(char *filename) { FILE *fp; char buf[100] ; fp = fopen(filename,"w"); while(fgets(buf, sizeof(buf),stdin) != NULL) { fputs(buf, fp); } fclose(fp); return ; } です。これらを組み合わせて少しいじると出来るみたいなのですが、できていません。ちなみに私が考えたプログラムは #include<stdio.h> int put_file_contents(char *filename); int main(int argc,char *argv[]) { int i; if(argc == 1){ printf("コマンドライン引数がありません\n"); return 1; } for(i = 0;i<argc;i++) printf("argv[%d]は「%s」です\n",i,argv[i]); put_file(i); return 0; } int put_file(char *filename) { FILE *fp; char buf[100]; int line_no; fp = fopen(filename,"r"); line_no = 1; while (fgets(buf,sizeof(buf),fp) != NULL){ printf("%3d: ",line_no); printf("%s",buf); line_no++; } fclose(fp); return 0; } です。コマンドライン引数は表示されるのですが、行番号が表示されません。どうしたらいいでしょうか??

  • セグメンテーション違反

    VC++からgccに移行してセグメンテーション違反が出るようになりました。VC++ではちゃんと動くのに、です…。 void enterData() { FILE *file_ptr; flights_record flights_array[25]; char in_string[10]; int index = 1; int repeat = TRUE; char ch; while(repeat) { printf("\nFlight ID => "); gets(flights_array[index].flightID); flights_array[index].recordNumber = index; printf("Enter more data (Y/N) => "); ch = toupper(getc(stdin)); putchar(ch); setbuf(stdin,NULL); index++; if(ch != 'Y') repeat = FALSE; fflush(stdin); } if((file_ptr = fopen("C:FLIGHTS.DTA","w+")) == NULL) { printf("Can't open filights file."); exit(0); } fwrite(flights_array, sizeof(flights_array), index, file_ptr); //←どうもここで止まるようです fclose(file_ptr); } 構造体の内容を"flightID"と"recordNumber"だけにして端折っていますが その他はそのままです。上のindex++;のせいかと思ってfwriteでindex-1にしても変わりません。 ちなみにVC++ではFLIGHTS.DTAが存在してても"w"だけで良かったのですがgccでは"w+"にしないと通りませんでした。 どこが怪しいところがあればご指摘戴けるとありがたいです。どうかよろしくお願いします。

  • バイナリファイルでランダムアクセスを行う

    初心者です。宜しくお願いします。 下記 text.bin にランダムアクセスするサンプルコードで一部理解できない箇所があります。 下から5行目のfreadの一つ目の引数 &num です。なぜ5のポインタなのか初心者にわかりやすく解説頂けないでしょうか? 宜しくお願い致します。 ■text.bin 80 60 22 50 75 ■サンプルコード #include <stdio.h> #define NUM 5 int main(void) { FILE *fp; int num; int i; fp = fopen("/Users/Documents/test1.bin", "rb"); if (fp == NULL) { printf("ファイルをオープンできませんでした。\n"); return 1; } printf("何番目のデータを読み込みますか?(1~5)\n"); scanf("%d", &i); fseek(fp, (i-1)*sizeof(int), SEEK_SET); fread(&num, sizeof(int), 1, fp); printf("%d番目のデータは%dです。\n", i, num); printf("<#message#>"); fclose(fp); return 0; }

  • バッファオーバーランの危険性検出について

    下に示すmsg_file.txtの内容を読み込んで表示するプログラムを使ってバッファオーバーランの危険性を検出するプログラムを作りたいのですが、どのように書き換えたら良いでしょうか。 プログラムソース 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define FILEPATH "msg_file.txt" 6 7 int main(); 8 void vuln(const char* line); 9 void stack_dump(void* ptr, int counts); 10 void hello(); 11 12 int main() 13 { 14 char linebuf[1024]; 15 FILE *fp; 16 long mark1 = 0x11111111; 17 memset(linebuf, 0, sizeof(linebuf)); 18 19 fp = fopen(FILEPATH, "r"); 20 fgets(linebuf, sizeof(linebuf)-1, fp); 21 fclose(fp); 22 23 vuln(linebuf); 24 25 printf("------------- end of main() -------------\n"); 26 } 27 28 void vuln(const char* line) 29 { 30 char msg[20]; 31 long mark2 = 0x22222222; 32 memset(msg, 0, sizeof(msg)); 33 34 strcpy(msg, line); 35 36 stack_dump(&mark2, 13); 37 38 printf("INPUT[%s]\n", msg); 39 } 40 41 void stack_dump(void* ptr, int counts) 42 { 43 int i; 44 unsigned long *ulong_ptr = (unsigned long *)ptr; 45 unsigned char uchar_buf[4]; 46 47 printf("-----------------------------------------\n"); 48 printf(" address | long var | +0 +1 +2 +3 | 0123\n"); 49 printf("-----------------------------------------\n"); 50 for(i=0; i<counts; i++) { 51 printf(" %08x| %08x", &ulong_ptr[i], ulong_ptr[i]); 52 memcpy(uchar_buf, &ulong_ptr[i], sizeof(uchar_buf)); 53 printf(" | %02x %02x %02x %02x", 54 uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]); 55 if(uchar_buf[0]<32 || uchar_buf[0]>126) uchar_buf[0] = '.'; 56 if(uchar_buf[1]<32 || uchar_buf[1]>126) uchar_buf[1] = '.'; 57 if(uchar_buf[2]<32 || uchar_buf[2]>126) uchar_buf[2] = '.'; 58 if(uchar_buf[3]<32 || uchar_buf[3]>126) uchar_buf[3] = '.'; 59 printf(" | %c%c%c%c\n", 60 uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]); 61 } 62 printf("-----------------------------------------\n"); 63 } 64 65 void hello() 66 { 67 printf("+----------+\n"); 68 printf("| HELLO! |\n"); 69 printf("+----------+\n"); 70 exit(0); 71 }

  • 作成したプログラムファイルの管理を行うプログラムというものを学校の課題

    作成したプログラムファイルの管理を行うプログラムというものを学校の課題で行っているのですが、 この課題の制作にあたって、手始めにファイルの保存と読み込みを行う関数を作ろうと思うのですが、ファイルを保存する関数(save)と読み込む関数(load)の作り方、ファイルポインタに格納する方法がわかりません。 現在の途中経過を示します。 #include <stdio.h> #include <stdlib.h> struct date {/*作成日付を格納*/ int year;/*年*/ int month;/*月*/ int day;/*日*/ }; struct record {/*レコード*/ char title[30];/*タイトル名*/ char stitle[50];/*副タイトル名*/ struct date adate;/*作成日付*/ char path[50];/*パス名(ファイルがどこのフォルダにあるか)*/ char category[30];/*分類*/ }; int save(struct record file)/*ファイルを保存する*/ { FILE *fp; int c; fp = fopen("program.txt","w"); if (fp == NULL){ fprintf(stderr,"Cannot open file: composition.txt\n"); return -1; } fprintf(""); fclose(fp); } int load(struct record file)/*ファイルを読み込む*/ { } int main() { int num; char file; int sortnum; printf("プログラムファイル管理プログラムへようこそ!\n"); do{ printf("何をしますか?\n"); printf("[0:終了、1:保存、2:読み込み]\n"); printf("入力してください: "); scanf("%d",&num); if(num==1 && num == 2){ printf("ファイル名を指定してください: "); scanf("%s",&file); if(num==1) save(file); if(num==2) load(file); }else printf("入力された数値が正しくありません。\n"); }while(num != 0) return 0; }

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • 別のファイルにあるレコードを各配列に格納したいです

    ファイル"DATA.dat"にあるレコードを配列"Record"にそれぞれ格納するプログラム考えてみましたが、なかなか動いてくれません。何かアドバイスをください。 DATA.datの内容 0001 0010 0011 0100 0101 : : Record配列にレコードを格納するイメージ Record[0] <- 0001 Record[1] <- 0010 Record[2] <- 0011 Record[3] <- 0100 Record[4] <- 0101     :     : 考えたプログラム #include <stdio.h> #include <stdlib.h> void main() { FILE *File_pt; char Record[100]; int i; //TimeLineファイルをOpenする if ( (File_pt = fopen("DATA.dat", "r")) != NULL){ for(i = 0 ; i < 5 ; i++){ if( (fscanf(File_pt, "%s", Record[i])) == EOF){ printf("各レコード格納失敗\n"); exit(1); } } //////格納されたレコードを表示する for(i = 0 ; i < 5 ; i++){ printf("%s\n",Record[i]); } fclose(File_pt); }else{ printf("失敗\n"); exit(1); } } まだ初心者なんでおねがいします。

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • 型によらないCSVファイルの読み込みC言語プログラ

    あらかじめ型のわかっているN行*M列のエクセルデータをCSV形式にし、 読み込むプログラムを作成しました。 そのプログラムを下に示します #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 23 #define M 6 /* データの区切り文字 */ #define SEP_DATA ',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン */ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し */ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換 */ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す */ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す */ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ */ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保 */ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(double[M]) * N); //malloc(sizeof(*csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化 */ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み */ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力 */ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } これをNとMがどんな値であれ読み込めるようにするにはどうすれいいでしょうか