Фактические изменения в функциональности? Была пара. Во-первых, вы должны аннулировать последнюю запись в данных после того, как вы скопировали ее вниз по списку. Во-вторых, вы должны пересчитать количество записей после того, как вы удалили некоторые из них.
На данный момент у вас нет хорошего способа остановки ввода, кроме EOF. Это означало, что я добавлял данные за один запуск программы; Затем мне пришлось запустить программу во второй раз, чтобы удалить некоторые данные. Однако, похоже, работает правильно. Я добавил ключи 1, 2, 3, 4, а затем удалил 2, 4, и в списке остались 1, 3, что мне кажется правильным.
Меня спросили об этом по электронной почте в результате ответа на связанный вопрос mmap и struct в C.< /em>
#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");
}
person
Jonathan Leffler
schedule
03.01.2015
not working
никому не помогает. Кроме того, размер файла никогда не меняется, поэтому в этом файле все еще есть1000
элементов. - person D3Hunter   schedule 03.01.2015