ちょっと変なことを思いつきました。
データの中に絶対に使用しない値があるとすれば、
それを削除マークにしてしまうというものです。
次のプログラムは、質問の問題とは異なり、
wc.out={1,6,2,43,123} が wc.out={5,6,2,43,123} に
なりませんが、削除をこんな風に処理すればどうで
しょうか、という例なので、よく読んで参考にして
みてはいかがでしょうか?
コード:
#include <stdio.h>
#define MAX_SIZE 10000
#define DELETED 99999999
char filename[256];
int data[MAX_SIZE];
int size;
int modified;
void menu(void)
{
puts(" m: display this menu\n"
" p: print data\n"
" r file: read data form file\n"
" a data: append data\n"
" d data: delete data\n"
" w [file]: write data to file\n"
" q: quit");
}
void print_data(void)
{
for (int i = 0; i < size; i++)
if (data[i] != DELETED) printf(" %d", data[i]);
printf("\n");
}
void read_data(const char *buf)
{
if (sscanf(buf+1, "%s", filename) != 1) {
puts("filename");
return;
}
FILE *fp = fopen(filename, "r");
if (!fp) {
printf("can't open %s\n", filename);
return;
}
for (size = 0; size < MAX_SIZE; size++)
if (fscanf(fp, "%d", &data[size]) != 1) break;
fclose(fp);
modified = 0;
}
void append_data(const char *buf)
{
int x;
if (sscanf(buf+1, "%d", &x) != 1) { puts("no data"); return; }
if (size >= MAX_SIZE) { puts("no space"); return; }
data[size++] = x;
modified = 1;
}
void delete_data(const char *buf)
{
int x, i;
if (sscanf(buf+1, "%d", &x) != 1) { puts("no data"); return; }
for (i = 0; i < size && data[i] != x; i++) ;
if (i >= size) { puts("not found"); return; }
data[i] = DELETED;
modified = 1;
}
void save_data(const char *buf)
{
if (filename[0] == '\0' && sscanf(buf+1, "%s", filename) != 1) {
puts("no filename"); return;
}
FILE *fp = fopen(filename, "w");
if (!fp) { printf("can't create %s\n", filename); return; }
for (int i = 0; i < size; i++)
if (data[i] != DELETED) fprintf(fp, "%d ", data[i]);
fclose(fp);
modified = 0;
}
int main(void)
{
char buf[1024];
menu();
while (printf(">> "), fgets(buf, sizeof buf, stdin)) {
if (buf[0] == 'm') menu();
else if (buf[0] == 'p') print_data();
else if (buf[0] == 'r') read_data(buf);
else if (buf[0] == 'a') append_data(buf);
else if (buf[0] == 'd') delete_data(buf);
else if (buf[0] == 's') save_data(buf);
else if (buf[0] == 'q') {
if (!modified) break;
printf("data modified. really quit[y/n]? ");
if (fgets(buf, sizeof buf, stdin) && buf[0] == 'y') break;
}
}
return 0;
}
実行例
コード:
m: display this menu
p: print data
r file: read data form file
a data: append data
d data: delete data
w [file]: write data to file
q: quit
>> r wc.out
>> p
1 6 2 43 123
>> a 5
>> p
1 6 2 43 123 5
>> d 1
>> p
6 2 43 123 5
>> s
>> q
めざせ、きれいなインデント。