#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#define MAX_USERS 100
#define MAX_ARTICLES 200
#define FILENAME_USERS "users.txt"
#define FILENAME_ARTICLES "articles.txt"
// 角色枚举
typedef enum {
ROLE_ADMIN,
ROLE_AUTHOR,
ROLE_READER
} UserRole;
// 文章类型枚举
typedef enum {
TYPE_POETRY,
TYPE_NOVEL,
TYPE_FAIRY_TALE
} ArticleType;
// 用户结构体
typedef struct {
char username[50];
char password[50];
UserRole role;
char gender;
int age;
} User;
// 文章结构体
typedef struct {
char title[100];
char author[50];
char publish_date[20];
ArticleType type;
char content[500];
} Article;
// 全局变量
User users[MAX_USERS];
Article articles[MAX_ARTICLES];
int userCount = 0;
int articleCount = 0;
User currentUser; // 当前登录用户
// 函数声明
void loadData();
void saveData();
void registerUser();
int login();
void showUserMenu();
void manageProfile();
void manageArticles();
void publishArticle();
void editArticle();
void viewArticles();
void searchArticle();
void viewMyArticles();
void browseArticles();
void displayArticle(int index);
void deleteArticle();
void listAllUsers();
const char *getRoleName(UserRole role) {
switch (role) {
case ROLE_ADMIN:
return "管理员";
case ROLE_AUTHOR:
return "作者";
case ROLE_READER:
return "读者";
default:
return "未知";
}
}
const char *getArticleTypeName(ArticleType type) {
switch (type) {
case TYPE_POETRY:
return "诗歌";
case TYPE_NOVEL:
return "小说";
case TYPE_FAIRY_TALE:
return "童话";
default:
return "未知";
}
}
// 加载数据
void loadData() {
// 加载用户数据
FILE *userFile = fopen(FILENAME_USERS, "r");
if (userFile) {
while (fscanf(userFile, "%49[^|]|%49[^|]|%d|%c|%d\n",
users[userCount].username,
users[userCount].password,
&users[userCount].role,
&users[userCount].gender,
&users[userCount].age) == 5) {
userCount++;
}
fclose(userFile);
}
// 加载文章数据
FILE *articleFile = fopen(FILENAME_ARTICLES, "r");
if (articleFile) {
while (fscanf(articleFile, "%99[^|]|%49[^|]|%19[^|]|%d|%499[^\n]\n",
articles[articleCount].title,
articles[articleCount].author,
articles[articleCount].publish_date,
&articles[articleCount].type,
articles[articleCount].content) == 5) {
articleCount++;
}
fclose(articleFile);
}
}
// 保存数据
void saveData() {
// 保存用户数据
FILE *userFile = fopen(FILENAME_USERS, "w");
for (int i = 0; i < userCount; i++) {
fprintf(userFile, "%s|%s|%d|%c|%d\n",
users[i].username,
users[i].password,
users[i].role,
users[i].gender,
users[i].age);
}
fclose(userFile);
// 保存文章数据
FILE *articleFile = fopen(FILENAME_ARTICLES, "w");
for (int i = 0; i < articleCount; i++) {
fprintf(articleFile, "%s|%s|%s|%d|%s\n",
articles[i].title,
articles[i].author,
articles[i].publish_date,
articles[i].type,
articles[i].content);
}
fclose(articleFile);
}
// 用户注册
void registerUser() {
if (userCount >= MAX_USERS) {
printf("用户数量已达上限!\n");
return;
}
User newUser;
printf("\n=== 用户注册 ===\n");
printf("请输入用户名: ");
scanf("%49s", newUser.username);
// 检查用户名是否已存在
for (int i = 0; i < userCount; i++) {
if (strcmp(users[i].username, newUser.username) == 0) {
printf("用户名已存在!\n");
return;
}
}
printf("请输入密码: ");
scanf("%49s", newUser.password);
int roleChoice;
printf("选择角色 (0-管理员, 1-作者, 2-读者): ");
scanf("%d", &roleChoice);
newUser.role = (UserRole)roleChoice;
printf("性别 (M/F): ");
scanf(" %c", &newUser.gender);
newUser.gender = toupper(newUser.gender);
printf("年龄: ");
scanf("%d", &newUser.age);
users[userCount++] = newUser;
saveData();
printf("注册成功!\n");
}
// 用户登录
int login() {
char username[50], password[50];
printf("\n=== 用户登录 ===\n");
printf("用户名: ");
scanf("%49s", username);
printf("密码: ");
scanf("%49s", password);
for (int i = 0; i < userCount; i++) {
if (strcmp(users[i].username, username) == 0 &&
strcmp(users[i].password, password) == 0) {
currentUser = users[i];
printf("登录成功!欢迎 %s (%s)\n",
currentUser.username, getRoleName(currentUser.role));
return 1;
}
}
printf("用户名或密码错误!\n");
return 0;
}
// 修改个人信息
void manageProfile() {
printf("\n=== 个人信息管理 ===\n");
printf("当前信息: \n");
printf("用户名: %s\n", currentUser.username);
printf("性别: %c\n", currentUser.gender);
printf("年龄: %d\n", currentUser.age);
int choice;
printf("\n1. 修改密码\n2. 修改性别\n3. 修改年龄\n0. 返回\n选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("新密码: ");
scanf("%49s", currentUser.password);
break;
case 2:
printf("新性别 (M/F): ");
scanf(" %c", ¤tUser.gender);
currentUser.gender = toupper(currentUser.gender);
break;
case 3:
printf("新年龄: ");
scanf("%d", ¤tUser.age);
break;
case 0:
return;
default:
printf("无效选择!\n");
}
// 更新全局用户数组
for (int i = 0; i < userCount; i++) {
if (strcmp(users[i].username, currentUser.username) == 0) {
users[i] = currentUser;
break;
}
}
saveData();
printf("信息更新成功!\n");
}
// 发布文章
void publishArticle() {
if (articleCount >= MAX_ARTICLES) {
printf("文章数量已达上限!\n");
return;
}
Article newArticle;
printf("\n=== 发布新文章 ===\n");
printf("标题: ");
scanf(" %[^\n]", newArticle.title); // 读取整行
// 检查标题是否已存在
for (int i = 0; i < articleCount; i++) {
if (strcmp(articles[i].title, newArticle.title) == 0) {
printf("标题已存在!\n");
return;
}
}
strcpy(newArticle.author, currentUser.username);
printf("发布日期 (YYYY-MM-DD): ");
scanf("%19s", newArticle.publish_date);
int typeChoice;
printf("类型 (0-诗歌, 1-小说, 2-童话): ");
scanf("%d", &typeChoice);
newArticle.type = (ArticleType)typeChoice;
printf("内容 (不超过500字符): ");
getchar(); // 清除缓冲区
fgets(newArticle.content, sizeof(newArticle.content), stdin);
newArticle.content[strcspn(newArticle.content, "\n")] = '\0'; // 移除换行符
articles[articleCount++] = newArticle;
saveData();
printf("文章发布成功!\n");
}
// 编辑文章
void editArticle() {
printf("\n=== 编辑文章 ===\n");
viewMyArticles();
if (articleCount == 0)
return;
int index;
printf("输入要编辑的文章编号 (-1取消): ");
scanf("%d", &index);
if (index < 0 || index >= articleCount) {
printf("无效编号!\n");
return;
}
// 检查权限:作者只能编辑自己的文章,管理员可以编辑所有
if (currentUser.role != ROLE_ADMIN &&
strcmp(articles[index].author, currentUser.username) != 0) {
printf("无权编辑此文章!\n");
return;
}
Article *art = &articles[index];
printf("\n当前标题: %s\n新标题: ", art->title);
getchar();
fgets(art->title, sizeof(art->title), stdin);
art->title[strcspn(art->title, "\n")] = '\0';
printf("新内容: ");
fgets(art->content, sizeof(art->content), stdin);
art->content[strcspn(art->content, "\n")] = '\0';
saveData();
printf("文章修改成功!\n");
}
// 浏览文章目录
void browseArticles() {
printf("\n=== 文章目录 ===\n");
printf("%-5s %-30s %-15s %-10s %-10s\n",
"ID", "标题", "作者", "类型", "发布日期");
for (int i = 0; i < articleCount; i++) {
printf("%-5d %-30s %-15s %-10s %-10s\n",
i, articles[i].title, articles[i].author,
getArticleTypeName(articles[i].type), articles[i].publish_date);
}
}
// 查看文章详情
void displayArticle(int index) {
if (index < 0 || index >= articleCount) {
printf("无效文章ID!\n");
return;
}
Article art = articles[index];
printf("\n=== 文章详情 ===\n");
printf("标题: %s\n", art.title);
printf("作者: %s\n", art.author);
printf("类型: %s\n", getArticleTypeName(art.type));
printf("发布日期: %s\n", art.publish_date);
printf("内容:\n%s\n", art.content);
}
// 搜索文章
void searchArticle() {
char title[100];
printf("\n=== 文章搜索 ===\n");
printf("输入文章标题: ");
scanf(" %[^\n]", title);
int found = 0;
for (int i = 0; i < articleCount; i++) {
if (strstr(articles[i].title, title) != NULL) {
displayArticle(i);
found = 1;
break;
}
}
if (!found) {
printf("未找到相关文章!\n");
}
}
// 查看我的文章
void viewMyArticles() {
printf("\n=== 我的文章 ===\n");
int count = 0;
for (int i = 0; i < articleCount; i++) {
if (strcmp(articles[i].author, currentUser.username) == 0) {
printf("[%d] %s (%s)\n", i, articles[i].title, articles[i].publish_date);
count++;
}
}
if (count == 0) {
printf("您还没有发布文章!\n");
}
}
// 删除文章
void deleteArticle() {
viewMyArticles();
if (articleCount == 0)
return;
int index;
printf("输入要删除的文章编号 (-1取消): ");
scanf("%d", &index);
if (index < 0 || index >= articleCount) {
printf("无效编号!\n");
return;
}
// 检查权限
if (currentUser.role != ROLE_ADMIN &&
strcmp(articles[index].author, currentUser.username) != 0) {
printf("无权删除此文章!\n");
return;
}
// 删除文章
for (int i = index; i < articleCount - 1; i++) {
articles[i] = articles[i + 1];
}
articleCount--;
saveData();
printf("文章删除成功!\n");
}
// 列出所有用户(管理员)
void listAllUsers() {
if (currentUser.role != ROLE_ADMIN) {
printf("权限不足!\n");
return;
}
printf("\n=== 用户列表 ===\n");
printf("%-20s %-10s %-6s %-4s\n", "用户名", "角色", "性别", "年龄");
for (int i = 0; i < userCount; i++) {
printf("%-20s %-10s %-6c %-4d\n",
users[i].username,
getRoleName(users[i].role),
users[i].gender,
users[i].age);
}
}
// 文章管理菜单
void manageArticles() {
int choice;
do {
printf("\n=== 文章管理 ===\n");
printf("1. 发布文章\n");
printf("2. 编辑文章\n");
printf("3. 查看我的文章\n");
printf("4. 删除文章\n");
printf("0. 返回主菜单\n");
printf("选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
publishArticle();
break;
case 2:
editArticle();
break;
case 3:
viewMyArticles();
break;
case 4:
deleteArticle();
break;
case 0:
break;
default:
printf("无效选择!\n");
}
} while (choice != 0);
}
// 主菜单
void mainMenu() {
int choice;
do {
printf("\n=== 主菜单 ===\n");
printf("1. 浏览文章\n");
printf("2. 搜索文章\n");
if (currentUser.role == ROLE_ADMIN || currentUser.role == ROLE_AUTHOR) {
printf("3. 文章管理\n");
}
printf("4. 个人信息管理\n");
if (currentUser.role == ROLE_ADMIN) {
printf("5. 用户管理\n");
}
printf("0. 退出系统\n");
printf("选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
browseArticles();
break;
case 2:
searchArticle();
break;
case 3:
if (currentUser.role == ROLE_ADMIN || currentUser.role == ROLE_AUTHOR) {
manageArticles();
} else {
printf("权限不足!\n");
}
break;
case 4:
manageProfile();
break;
case 5:
if (currentUser.role == ROLE_ADMIN) {
listAllUsers();
} else {
printf("权限不足!\n");
}
break;
case 0:
printf("感谢使用!\n");
exit(0);
default:
printf("无效选择!\n");
}
} while (1);
}
// 用户菜单
void showUserMenu() {
int choice;
do {
printf("\n=== 主界面 ===\n");
printf("1. 登录\n");
printf("2. 注册\n");
printf("0. 退出\n");
printf("选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
if (login()) {
mainMenu();
}
break;
case 2:
registerUser();
break;
case 0:
printf("感谢使用!\n");
exit(0);
default:
printf("无效选择!\n");
}
} while (1);
}
int main() {
loadData();
showUserMenu();
return 0;
}
浏览文章可以查看文章详情