从 mmaped 结构数组中删除结构
Remove struct from mmaped array of structs
问题:我有一个名为 "med" 的结构来保存有关药物的信息(密钥、名称、最小数量和数量),每个药物都有一个唯一的密钥。我使用 mmap 将这些结构的数组存储在内存映射文件中。现在我想从数组中删除特定的 med(结构),但它不起作用...
代码:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define NUM_MEDS 1000
#define FILESIZE (NUM_MEDS * sizeof(struct med))
struct med
{
int key;
char name[25];
int quant_min;
int quant;
};
int main(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open("meds.dat", O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
/* Now the file is ready to be mmapped. */
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
struct med m;
printf("Please enter the code of med: ");
scanf("%d",&m.key);
int j;
for (j = 0; j < NUM_MEDS; j++)
{
if (m.key == map[j].key)
{
for(j; j < NUM_MEDS - 1; j++)
{
map[j] = map[j+1];
}
printf("Med %d removed with success\n",m.key);
break;
}
}
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
}
close(fd);
return 0;
}
有人可以帮忙吗?
功能上的实际变化?有一对。首先,在将数据复制到列表中后,必须使数据中的最后一个条目无效。其次,您必须在删除一些条目后重新计算条目数。
目前,除了 EOF 之外,您没有其他好的方法来停止输入。那意味着我用一个 运行 的程序添加了数据;然后我不得不 运行 程序第二次删除一些数据。但是,它似乎工作正常。我添加了键 1、2、3、4,然后删除了 2、4,剩下的列表是 1、3,这对我来说似乎是正确的。
我在回答相关问题 mmap and struct in C 后通过电子邮件询问了这个问题。
#define _XOPEN_SOURCE 800
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define FILEPATH "/tmp/mmapped.bin"
#define NUM_MEDS 1000
#define FILESIZE (NUM_MEDS * sizeof(struct med))
struct med
{
int key;
char name[25];
int quant_min;
int quant;
};
static int find_num_entries(struct med *map, int max_meds);
static int get_new_key(struct med *map, int num_meds, int *key);
static int med_in_map(struct med *map, int num_meds, int key);
static int remove_key_med(struct med *map, int num_meds, int *key);
static int remove_med(struct med *map, int num_meds, int key);
static void insert_med_mmap(void);
static void interface(void);
static void list_meds_mmap(void);
static void load_meds_mmap(void);
static void print_med(char *tag, const struct med *med);
static void remove_med_mmap(void);
static void search_med_mmap(void);
int main(void)
{
interface();
return 0;
}
// interface
void interface(void)
{
printf("\n");
printf("=> Management and administration of Meds \n");
printf("\n");
printf("=> Mmap version \n");
printf("\n");
printf("Choose your operation \n");
printf("1- Insert med \n");
printf("2- Remove med \n");
printf("3- Search med \n");
printf("4- List meds ordered by name \n");
printf("5- Load meds \n");
printf("6- Exit \n");
int a;
scanf("%d", &a);
switch (a)
{
case 1:
printf("\n");
printf("Insert med \n");
insert_med_mmap();
break;
case 2:
printf("\n");
printf("Remove med \n");
remove_med_mmap();
break;
case 3:
printf("\n");
printf("Search med \n");
search_med_mmap();
break;
case 4:
printf("\n");
printf("List meds ordered by name \n");
list_meds_mmap();
break;
case 5:
printf("\n");
load_meds_mmap();
break;
case 6:
return;
}
}
static void print_med(char *tag, const struct med *med)
{
printf("%s: %4d: Q(%2d, min %2d): %s\n",
tag, med->key, med->quant, med->quant_min, med->name);
}
static int med_in_map(struct med *map, int num_meds, int key)
{
int i;
for (i = 0; i < num_meds; i++)
{
if (key == map[i].key)
{
printf("The med with key %d already exists in the file. \n", key);
return 1;
}
}
return 0;
}
static int get_new_key(struct med *map, int num_meds, int *key)
{
while (printf("Type the key of med: ") > 0 && scanf("%d", key) == 1)
{
if (med_in_map(map, num_meds, *key) == 0)
return 0;
}
return EOF;
}
static int find_num_entries(struct med *map, int max_meds)
{
int i;
for (i = 0; i < max_meds; i++)
{
if (map[i].key == 0)
break;
}
return i;
}
static int remove_med(struct med *map, int num_meds, int key)
{
int i;
for (i = 0; i < num_meds; i++)
{
if (key == map[i].key)
{
for ( ; i < num_meds - 1; i++)
{
map[i] = map[i + 1];
}
printf("Med %d removed with sucess\n", key);
map[i].key = 0;
map[i].name[0] = '[=10=]';
map[i].quant = 0;
map[i].quant_min = 0;
return 0;
}
}
return 1;
}
static int remove_key_med(struct med *map, int num_meds, int *key)
{
while (printf("Type the key of med: ") > 0 && scanf("%d", key) == 1)
{
if (remove_med(map, num_meds, *key) == 0)
return 0;
}
return EOF;
}
// load meds
void load_meds_mmap(void)
{
printf("Test \n");
}
// insert med with mmap
void insert_med_mmap(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open(FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Input loop */
int num_meds;
for (num_meds = find_num_entries(map, NUM_MEDS); num_meds < NUM_MEDS; num_meds++)
{
struct med m;
memset(&m, '[=10=]', sizeof(m));
if (get_new_key(map, num_meds, &m.key) == EOF)
break;
printf("Name of med: ");
if (scanf("%s", m.name) != 1)
break;
printf("Quant. min. of med: ");
if (scanf("%d", &m.quant_min) != 1)
break;
printf("Quant. of med: ");
if (scanf("%d", &m.quant) != 1)
break;
map[num_meds] = m;
printf("Med %d saved.\n", m.key);
}
/* Output loop */
printf("\nRecorded meds:\n");
int i;
for (i = 0; i < num_meds; i++)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "M%.4d", i);
print_med(buffer, &map[i]);
}
/* Don't forget to free the mmapped memory */
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
/* Un-mmapping doesn't close the file, so we still need to do that. */
close(fd);
}
// remove med with mmap
void remove_med_mmap(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open(FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
/* Now the file is ready to be mmapped. */
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Input loop */
int num_meds;
for (num_meds = find_num_entries(map, NUM_MEDS); num_meds < NUM_MEDS; num_meds++)
{
struct med m;
memset(&m, '[=10=]', sizeof(m));
if (remove_key_med(map, num_meds, &m.key) == EOF)
break;
}
/* Partial bug fix */
num_meds = find_num_entries(map, NUM_MEDS);
/* Output loop */
printf("\nRecorded meds:\n");
int i;
for (i = 0; i < num_meds; i++)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "M%.4d", i);
print_med(buffer, &map[i]);
}
/* Don't forget to free the mmapped memory */
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
/* Un-mmapping doesn't close the file, so we still need to do that. */
close(fd);
return;
}
void search_med_mmap(void)
{
printf("Test \n");
}
void list_meds_mmap(void)
{
printf("Test \n");
}
问题:我有一个名为 "med" 的结构来保存有关药物的信息(密钥、名称、最小数量和数量),每个药物都有一个唯一的密钥。我使用 mmap 将这些结构的数组存储在内存映射文件中。现在我想从数组中删除特定的 med(结构),但它不起作用...
代码:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define NUM_MEDS 1000
#define FILESIZE (NUM_MEDS * sizeof(struct med))
struct med
{
int key;
char name[25];
int quant_min;
int quant;
};
int main(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open("meds.dat", O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
/* Now the file is ready to be mmapped. */
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
struct med m;
printf("Please enter the code of med: ");
scanf("%d",&m.key);
int j;
for (j = 0; j < NUM_MEDS; j++)
{
if (m.key == map[j].key)
{
for(j; j < NUM_MEDS - 1; j++)
{
map[j] = map[j+1];
}
printf("Med %d removed with success\n",m.key);
break;
}
}
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
}
close(fd);
return 0;
}
有人可以帮忙吗?
功能上的实际变化?有一对。首先,在将数据复制到列表中后,必须使数据中的最后一个条目无效。其次,您必须在删除一些条目后重新计算条目数。
目前,除了 EOF 之外,您没有其他好的方法来停止输入。那意味着我用一个 运行 的程序添加了数据;然后我不得不 运行 程序第二次删除一些数据。但是,它似乎工作正常。我添加了键 1、2、3、4,然后删除了 2、4,剩下的列表是 1、3,这对我来说似乎是正确的。
我在回答相关问题 mmap and struct in C 后通过电子邮件询问了这个问题。
#define _XOPEN_SOURCE 800
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define FILEPATH "/tmp/mmapped.bin"
#define NUM_MEDS 1000
#define FILESIZE (NUM_MEDS * sizeof(struct med))
struct med
{
int key;
char name[25];
int quant_min;
int quant;
};
static int find_num_entries(struct med *map, int max_meds);
static int get_new_key(struct med *map, int num_meds, int *key);
static int med_in_map(struct med *map, int num_meds, int key);
static int remove_key_med(struct med *map, int num_meds, int *key);
static int remove_med(struct med *map, int num_meds, int key);
static void insert_med_mmap(void);
static void interface(void);
static void list_meds_mmap(void);
static void load_meds_mmap(void);
static void print_med(char *tag, const struct med *med);
static void remove_med_mmap(void);
static void search_med_mmap(void);
int main(void)
{
interface();
return 0;
}
// interface
void interface(void)
{
printf("\n");
printf("=> Management and administration of Meds \n");
printf("\n");
printf("=> Mmap version \n");
printf("\n");
printf("Choose your operation \n");
printf("1- Insert med \n");
printf("2- Remove med \n");
printf("3- Search med \n");
printf("4- List meds ordered by name \n");
printf("5- Load meds \n");
printf("6- Exit \n");
int a;
scanf("%d", &a);
switch (a)
{
case 1:
printf("\n");
printf("Insert med \n");
insert_med_mmap();
break;
case 2:
printf("\n");
printf("Remove med \n");
remove_med_mmap();
break;
case 3:
printf("\n");
printf("Search med \n");
search_med_mmap();
break;
case 4:
printf("\n");
printf("List meds ordered by name \n");
list_meds_mmap();
break;
case 5:
printf("\n");
load_meds_mmap();
break;
case 6:
return;
}
}
static void print_med(char *tag, const struct med *med)
{
printf("%s: %4d: Q(%2d, min %2d): %s\n",
tag, med->key, med->quant, med->quant_min, med->name);
}
static int med_in_map(struct med *map, int num_meds, int key)
{
int i;
for (i = 0; i < num_meds; i++)
{
if (key == map[i].key)
{
printf("The med with key %d already exists in the file. \n", key);
return 1;
}
}
return 0;
}
static int get_new_key(struct med *map, int num_meds, int *key)
{
while (printf("Type the key of med: ") > 0 && scanf("%d", key) == 1)
{
if (med_in_map(map, num_meds, *key) == 0)
return 0;
}
return EOF;
}
static int find_num_entries(struct med *map, int max_meds)
{
int i;
for (i = 0; i < max_meds; i++)
{
if (map[i].key == 0)
break;
}
return i;
}
static int remove_med(struct med *map, int num_meds, int key)
{
int i;
for (i = 0; i < num_meds; i++)
{
if (key == map[i].key)
{
for ( ; i < num_meds - 1; i++)
{
map[i] = map[i + 1];
}
printf("Med %d removed with sucess\n", key);
map[i].key = 0;
map[i].name[0] = '[=10=]';
map[i].quant = 0;
map[i].quant_min = 0;
return 0;
}
}
return 1;
}
static int remove_key_med(struct med *map, int num_meds, int *key)
{
while (printf("Type the key of med: ") > 0 && scanf("%d", key) == 1)
{
if (remove_med(map, num_meds, *key) == 0)
return 0;
}
return EOF;
}
// load meds
void load_meds_mmap(void)
{
printf("Test \n");
}
// insert med with mmap
void insert_med_mmap(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open(FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Input loop */
int num_meds;
for (num_meds = find_num_entries(map, NUM_MEDS); num_meds < NUM_MEDS; num_meds++)
{
struct med m;
memset(&m, '[=10=]', sizeof(m));
if (get_new_key(map, num_meds, &m.key) == EOF)
break;
printf("Name of med: ");
if (scanf("%s", m.name) != 1)
break;
printf("Quant. min. of med: ");
if (scanf("%d", &m.quant_min) != 1)
break;
printf("Quant. of med: ");
if (scanf("%d", &m.quant) != 1)
break;
map[num_meds] = m;
printf("Med %d saved.\n", m.key);
}
/* Output loop */
printf("\nRecorded meds:\n");
int i;
for (i = 0; i < num_meds; i++)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "M%.4d", i);
print_med(buffer, &map[i]);
}
/* Don't forget to free the mmapped memory */
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
/* Un-mmapping doesn't close the file, so we still need to do that. */
close(fd);
}
// remove med with mmap
void remove_med_mmap(void)
{
int fd;
int result;
struct med *map; /* mmapped array of structs */
fd = open(FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = ftruncate(fd, FILESIZE);
if (result == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
/* Now the file is ready to be mmapped. */
map = (struct med *)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Input loop */
int num_meds;
for (num_meds = find_num_entries(map, NUM_MEDS); num_meds < NUM_MEDS; num_meds++)
{
struct med m;
memset(&m, '[=10=]', sizeof(m));
if (remove_key_med(map, num_meds, &m.key) == EOF)
break;
}
/* Partial bug fix */
num_meds = find_num_entries(map, NUM_MEDS);
/* Output loop */
printf("\nRecorded meds:\n");
int i;
for (i = 0; i < num_meds; i++)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "M%.4d", i);
print_med(buffer, &map[i]);
}
/* Don't forget to free the mmapped memory */
if (munmap(map, FILESIZE) == -1)
{
perror("Error un-mmapping the file");
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
/* Un-mmapping doesn't close the file, so we still need to do that. */
close(fd);
return;
}
void search_med_mmap(void)
{
printf("Test \n");
}
void list_meds_mmap(void)
{
printf("Test \n");
}