はじめての C

昨年の 9月から そのままに なってた アドレスブックの code を なんとか 動かせるように してみた。 まちがってる 可能性も あるけど ...

/* addbook.c */
#include <stdio.h>
#include "addbook.h"

int main(int argc, char **argv)
{
PERSON add_book[MAX_PSN];
int c;

long last;
int record;

FILE *fp;

if (argc != 2) {
fprintf(stderr, "Usage: ./add_book [file]\n");
exit(1);
}
if )((fp = fopen(argv[1], "a+b"))( == NULL) {
fprintf(stderr, "Can't open %s.\n", argv[1]);
exit(2);
}

puts ("Press [ctrl + d] at the time of finish.");

for (c = 0; c < MAX_PSN; c++) {
puts("Enter the name.");
if (fgets(add_book[c].name, MAX_NAME, stdin) == 0)
break;
else {
puts("Now enter the postal code.");
fgets(add_book[c].postal_code, MAX_PC, stdin);
puts("Now enter the address.");
fgets(add_book[c].address, MAX_ADDR, stdin);
puts("Now enter the phone number.");
fgets(add_book[c].phone, MAX_PHN, stdin);
}
}
rewind(fp);

heapsort(add_book, c);

fwrite(add_book, sizeof(PERSON), c, fp);

fclose(fp);

return 0;
}

/* heapsort.c */
#include <string.h>
#include "addbook.h"

void swap();
void shift();

void heapsort(PERSON a[], int n)
{
int left, right;

left = n / 2 + 1;
right = n;

while (left > 1)
shift(a, --left, right);
while (right > 1) {
swap(a, 1, right);
shift(a, 1, --right);
}
}

void swap(PERSON a[], int i, int j)
{
PERSON tmp;

tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}

void shift(PERSON a[], int left, int right)
{
int i, j;
PERSON tmp;

i = left;
j = 2 * i;
tmp = a[left];

while (j <= right) {
if (j < right)
if (strcmp(a[j].name, a[j + 1].name) < 0)
j++;
if (strcmp(tmp.name, a[j].name) >= 0)
break;
a[i] = a[j];
i = j;
j = 2 * i;
}
a[i] = tmp;
}

/* findphn.c */
#include <stdio.h>
#include <string.h>
#include "addbook.h"

#define SEEK_SET 0
#define SEEK_END 2

char * b_search();

int main(int argc, char **argv)
{
char name[MAX_NAME + 1];
char *phone;

long last;
int record;

FILE *fp;

if (argc != 2) {
fprintf(stderr, "Usage; ./findphn [file]\n");
exit(1);
}

if )((fp = fopen(argv[1], "rb"))( == NULL) {
fprintf(stderr, "Can't open %s.\n", argv[1]);
exit(2);
}

fseek(fp, 0L, SEEK_END);
last = ftell(fp);
record = (int)last / sizeof(PERSON);

printf("record = %d\n", record);

puts("Enter the name.");
fgets(name, MAX_NAME, stdin);

if )((phone = b_search(name, fp, record))( != NULL)
fprintf(stdout, "%s <- %s", phone, name);
else
fprintf(stdout, "Can't find %s.", name);

fclose(fp);
}

char *b_search(char *x, FILE *fp, int n)
{
int low, high, mid;
static PERSON who;

low = 0;
high = n;

while (low <= high) {
mid = (low + high) / 2;
fseek(fp, (mid - 1) * sizeof(PERSON), SEEK_SET);
fread(&who, sizeof(PERSON), 1, fp);
if (strcmp(x, who.name) > 0)
low = mid + 1;
else
return who.phone;
}
return NULL;
}

/* addbook.h */
#define MAX_NAME 50 + 1
#define MAX_PC 12 + 1
#define MAX_ADDR 100 + 1
#define MAX_PHN 12 + 1
#define MAX_PSN 300 + 1

typedef struct {
char name[MAX_NAME];
char postal_code[MAX_PC];
char address[MAX_ADDR];
char phone[MAX_PHN];
} PERSON;

void heapsort();

$ cc -c addbook.c heapsort.c
$ cc -o addbook addbook.o heapsort.o
$ cc -o findphn findphn.c
heapsort.c と findphn.c を 説明しようと 思ったが、すでに チカラ 尽きました o ...Lr
(追記) 使用してない 変数と マクロを 削除。