问题:我有一个名为" med"保持有关药物(关键字,名称,最小数量和数量)的信息,每个医学院都有一个唯一的关键。我使用mmap将这些结构的数组存储在内存映射文件中。现在我想从数组中删除一个特定的med(struct),但它不起作用......
代码:
#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;
}
有人可以帮忙吗?
答案 0 :(得分:1)
功能的实际变化?有一对。首先,在将数据下载到列表中之后,必须使数据中的最后一个条目无效。其次,您必须在删除一些条目后重新计算条目数。
目前,除了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] = '\0';
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, '\0', 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, '\0', 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");
}