Skip to content

Instantly share code, notes, and snippets.

@bojieli
Created December 17, 2014 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bojieli/b3a93b9861ca9ce30b98 to your computer and use it in GitHub Desktop.
Save bojieli/b3a93b9861ca9ce30b98 to your computer and use it in GitHub Desktop.
Programming-in-C/141217
/* File format:
* Number of couples | record for couple 1 | record for couple 2...
* int | No. | boy name | girl name | next pointer | ...
* | int | string | string | pointer |
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_LEN 64
struct couple *createCPLL(FILE *fp);
int file2print(FILE *fp);
int main()
{
FILE *fp;
if ((fp = fopen("couple2.out", "w")) == NULL) {
printf("Can not open this file couple2.txt\n");
return 0;
}
createCPLL(fp);
fclose(fp);
if ((fp = fopen("couple2.out", "r")) == NULL) {
printf("Can not open this file couple2.txt\n");
return 0;
}
file2print(fp);
fclose(fp);
return 0;
}
/* declare a struct */
struct couple
{
int No;
char boy_name[NAME_LEN];
char girl_name[NAME_LEN];
struct couple *next;
};
/* a function to create linked list: tail-insert */
struct couple *createCPLL(FILE *fp)
{
unsigned int count = 0;
struct couple *head = (struct couple *)malloc(sizeof(struct couple));
struct couple *curr;
memset(head, 0, sizeof(struct couple));
while (1) {
struct couple *newcp;
int No;
printf("Please input Number of a couple, enter 0 to exit: ");
scanf("%d", &No);
if (No == 0)
break;
newcp = (struct couple *)malloc(sizeof(struct couple));
newcp->No = No;
printf("Boy's name: ");
scanf("%63s", newcp->boy_name);
printf("Girl's name: ");
scanf("%63s", newcp->girl_name);
++count;
newcp->next = head->next;
head->next = newcp;
}
// write file
fwrite(&count, sizeof(int), 1, fp);
curr = head->next;
while (curr != NULL) {
fwrite(curr, sizeof(struct couple), 1, fp);
curr = curr->next;
}
return head;
}
/* you need a function to printf your linked list to check */
int file2print(FILE *fp)
{
unsigned int i, count;
struct couple *head = (struct couple *)malloc(sizeof(struct couple));
struct couple *curr;
memset(head, 0, sizeof(struct couple));
// read file
fread(&count, sizeof(int), 1, fp);
for (i = 0; i < count; i++) {
struct couple *newcp = (struct couple *)malloc(sizeof(struct couple));
fread(newcp, sizeof(struct couple), 1, fp);
newcp->next = head->next;
head->next = newcp;
}
// print
printf("Found %d couples\n", count);
curr = head->next;
while (curr != NULL) {
printf("No.%d couple is %s and %s\n", curr->No, curr->boy_name, curr->girl_name);
curr = curr->next;
}
return 0;
}
@bojieli
Copy link
Author

bojieli commented Dec 17, 2014

有这么几处改进:

  1. 文件开头写入 couple 的数目,不要依赖全局变量
  2. 使用带“哨兵”的链表,也就是链表 head 是哨兵,不存放实际数据,简化链表操作(不需对首个元素做特殊处理)
  3. 读入用户输入时,要防止缓冲区溢出(%63s 而非 %s)
  4. 从文件中读入后,把链表的数据结构重新建立起来,而不只是简单打印结果
  5. while 循环前面的 printf 语句不需要重复,只要在 while(1) 内加入 break 即可,重复代码是很不好的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment