通讯录数据文件格式:编号<Tab>姓名<Tab>手机<Tab>固定电话<Tab>地址<Tab> contack.data 1 张三 13888888888 028-88888888 成都工业学院xxx 2 李四 13888888888 028-88888888 成都工业学院xxx
时间: 2025-06-10 11:45:10 浏览: 16
以下是一个完整的C语言程序,用于读取和写入通讯录数据文件,并使用`fcntl()`函数实现文件记录锁(行级锁)。此外,我会详细解释代码的工作原理以及如何在Linux下编写、编译、运行和调试该程序。
### C语言代码实现
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define MAX_LINE 256
// 定义联系人结构体
typedef struct {
int id;
char name[32];
char mobile[16];
char phone[16];
char address[64];
} Contact;
// 函数声明
void add_contact(int fd, const Contact *contact);
void display_contacts(int fd);
int main() {
// 打开或创建文件 contact.data
int fd = open("contact.data", O_RDWR | O_CREAT, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 添加新联系人
Contact new_contact = {3, "王五", "13999999999", "028-99999999", "成都工业学院yyy"};
add_contact(fd, &new_contact);
// 显示所有联系人
display_contacts(fd);
close(fd); // 关闭文件
return 0;
}
// 添加联系人的函数
void add_contact(int fd, const Contact *contact) {
struct flock lock;
lock.l_type = F_WRLCK; // 写锁
lock.l_whence = SEEK_END;
lock.l_start = 0;
lock.l_len = 0; // 锁定整个文件末尾
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl");
return;
}
// 将联系人信息写入文件
lseek(fd, 0, SEEK_END); // 移动到文件末尾
char buffer[MAX_LINE];
snprintf(buffer, sizeof(buffer), "%d\t%s\t%s\t%s\t%s\n",
contact->id, contact->name, contact->mobile, contact->phone, contact->address);
write(fd, buffer, strlen(buffer));
lock.l_type = F_UNLCK; // 解锁
fcntl(fd, F_SETLK, &lock);
}
// 显示所有联系人的函数
void display_contacts(int fd) {
struct flock lock;
lock.l_type = F_RDLCK; // 读锁
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0; // 锁定整个文件
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl");
return;
}
lseek(fd, 0, SEEK_SET); // 移动到文件开头
char buffer[MAX_LINE];
printf("编号\t姓名\t手机\t固定电话\t地址\n");
while (read(fd, buffer, sizeof(buffer)) > 0) {
printf("%s", buffer);
memset(buffer, 0, sizeof(buffer));
}
lock.l_type = F_UNLCK; // 解锁
fcntl(fd, F_SETLK, &lock);
}
```
---
### 回答问题-给出解释
#### 1. 程序功能
- **读写通讯录**:程序实现了对通讯录数据文件的读写操作。
- **文件锁机制**:通过`fcntl()`函数为文件加锁,确保多进程环境下的数据一致性。
- **添加联系人**:`add_contact`函数负责将新的联系人信息追加到文件末尾。
- **显示联系人**:`display_contacts`函数负责从文件中读取所有联系人信息并打印。
#### 2. 关键点
- **文件打开模式**:
- 使用`O_RDWR | O_CREAT`模式打开文件,如果文件不存在则创建。
- 权限设置为`0644`,表示文件可由用户读写,其他用户只能读。
- **文件锁**:
- `F_WRLCK`:写锁,防止其他进程同时写入。
- `F_RDLCK`:读锁,允许多个进程同时读取。
- `F_UNLCK`:解锁。
- **定位文件指针**:
- 使用`lseek(fd, 0, SEEK_END)`移动到文件末尾。
- 使用`lseek(fd, 0, SEEK_SET)`返回文件开头。
- **格式化输出**:
- 使用`snprintf()`生成符合要求的字符串格式。
- 使用`write()`将字符串写入文件。
#### 3. Linux下编写、编译、运行、调试的过程
- **编写**:将上述代码保存为`contact.c`。
- **编译**:在终端中执行`gcc contact.c -o contact`进行编译。
- **运行**:执行`./contact`运行程序,查看输出结果。
- **调试**:可以使用`gdb`调试工具,执行`gdb ./contact`进入调试模式,设置断点、单步执行等。
---
###
阅读全文
相关推荐



