Free E-Book list

Reprint from http://coolshell.cn/articles/2775.html

在StackOverflow上,有人要打算收集个免费电子书的列表,结果很快就有人分享了一个列表。很不错,我就转过来了。原帖的地址在http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books (注意:有些连接可能会被墙掉)

List of Free Programming books (compiled): Meta-List

Graphics Programming

Language Agnostic

ASP.NET MVC:

Assembly Language

Bash

C/C++

C#

  • See .NET below

Django

Forth

Git

Haskell

Java

JavaScript

Linux

Lisp

Lua

Maven

Mercurial

.NET (C#)

NoSQL

Objective-C

Parrot / Perl 6

Perl

PHP

PowerShell

Prolog

PostgreSQL

Python

Ruby

Scala

Scheme

SmallTalk

Subversion

*SQL (Implementation agnostic) *

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 100 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef struct { char name[50]; char password[20]; float balance; } User; typedef struct { char title[100]; char author[50]; float price; int status; // 0: available, 1: sold } Book; typedef struct { void *data; int length; int elemSize; } SeqList; // 初始化线性表 Status InitList(SeqList *L, int elemSize) { L->data = malloc(MAX_SIZE * elemSize); if (!L->data) return OVERFLOW; L->length = 0; L->elemSize = elemSize; return OK; } // 销毁线性表 Status DestroyList(SeqList *L) { if (L->data) { free(L->data); L->data = NULL; L->length = 0; } return OK; } // 插入元素 Status ListInsert(SeqList *L, int i, void *e) { if (i < 1 || i > L->length + 1) return ERROR; if (L->length >= MAX_SIZE) return ERROR; for (int j = L->length; j >= i; j--) { memmove((char *)L->data + (j * L->elemSize), (char *)L->data + ((j - 1) * L->elemSize), L->elemSize); } memcpy((char *)L->data + ((i - 1) * L->elemSize), e, L->elemSize); L->length++; return OK; } // 删除元素 Status ListDelete(SeqList *L, int i, void *e) { if (i < 1 || i > L->length) return ERROR; memcpy(e, (char *)L->data + ((i - 1) * L->elemSize), L->elemSize); for (int j = i; j < L->length; j++) { memmove((char *)L->data + ((j - 1) * L->elemSize), (char *)L->data + (j * L->elemSize), L->elemSize); } L->length--; return OK; } // 查找元素 int LocateElem(SeqList L, void *e, int (*compare)(void *, void *)) { for (int i = 0; i < L.length; i++) { if ((*compare)((char *)L.data + (i * L.elemSize), e) == 0) { return i + 1; } } return 0; } // 获取元素 Status GetElem(SeqList L, int i, void *e) { if (i < 1 || i > L.length) return ERROR; memcpy(e, (char *)L.data + ((i - 1) * L.elemSize), L.elemSize); return OK; } // 用户比较函数 int CompareUser(void *a, void *b) { User *user1 = (User *)a; User *user2 = (User *)b; return strcmp(user1->name, user2->name); } // 书籍比较函数 int CompareBook(void *a, void *b) { Book *book1 = (Book *)a; Book *book2 = (Book *)b; return strcmp(book1->title, book2->title); } // 打印用户信息 void PrintUser(User u) { printf("用户名: %s, 余额: %.2f\n", u.name, u.balance); } // 打印书籍信息 void PrintBook(Book b) { printf("书名: %s, 作者: %s, 价格: %.2f, 状态: %s\n", b.title, b.author, b.price, b.status == 0 ? "可售" : "已售"); } // 保存数据到文件 void SaveData(SeqList userList, SeqList bookList) { FILE *file = fopen("data.dat", "wb"); if (file) { fwrite(&userList.length, sizeof(int), 1, file); fwrite(userList.data, userList.elemSize, userList.length, file); fwrite(&bookList.length, sizeof(int), 1, file); fwrite(bookList.data, bookList.elemSize, bookList.length, file); fclose(file); printf("数据保存成功!\n"); } else { printf("无法保存数据!\n"); } } // 加载数据从文件 void LoadData(SeqList *userList, SeqList *bookList) { FILE *file = fopen("data.dat", "rb"); if (file) { fread(&userList->length, sizeof(int), 1, file); userList->data = realloc(userList->data, userList->length * userList->elemSize); fread(userList->data, userList->elemSize, userList->length, file); fread(&bookList->length, sizeof(int), 1, file); bookList->data = realloc(bookList->data, bookList->length * bookList->elemSize); fread(bookList->data, bookList->elemSize, bookList->length, file); fclose(file); printf("数据加载成功!\n"); } else { printf("无法加载数据!\n"); } } // 主菜单 void MainMenu() { SeqList userList, bookList; User newUser, deleteUser, loginUser; Book newBook, deleteBook, modifyBook; int choice, pos, userId, bookId; float amount; InitList(&userList, sizeof(User)); InitList(&bookList, sizeof(Book)); LoadData(&userList, &bookList); while (1) { printf("\n--- 主菜单 ---\n"); printf("1. 注册用户\n"); printf("2. 删除用户\n"); printf("3. 登录用户\n"); printf("4. 添加书籍\n"); printf("5. 删除书籍\n"); printf("6. 修改书籍信息\n"); printf("7. 查询书籍\n"); printf("8. 购买书籍\n"); printf("9. 查询余额\n"); printf("10. 充值\n"); printf("11. 查看所有用户信息\n"); printf("12. 导出数据\n"); printf("13. 退出并保存\n"); printf("请输入您的选择: "); scanf("%d", &choice); switch (choice) { case 1: printf("请输入用户名和密码: "); scanf("%s%s", newUser.name, newUser.password); newUser.balance = 0.0; if (ListInsert(&userList, userList.length + 1, &newUser) == OK) { printf("用户注册成功!\n"); } else { printf("注册失败!\n"); } break; case 2: printf("请输入要删除的用户名: "); scanf("%s", deleteUser.name); pos = LocateElem(userList, &deleteUser, CompareUser); if (pos != 0) { ListDelete(&userList, pos, &deleteUser); printf("用户删除成功!\n"); } else { printf("用户不存在!\n"); } break; case 3: printf("请输入用户名和密码: "); scanf("%s%s", loginUser.name, loginUser.password); if (LocateElem(userList, &loginUser, CompareUser) != 0) { printf("登录成功!\n"); userId = LocateElem(userList, &loginUser, CompareUser); } else { printf("用户名或密码错误!\n"); } break; case 4: printf("请输入书名、作者和价格: "); scanf("%s%s%f", newBook.title, newBook.author, &newBook.price); newBook.status = 0; if (ListInsert(&bookList, bookList.length + 1, &newBook) == OK) { printf("书籍添加成功!\n"); } else { printf("添加书籍失败!\n"); } break; case 5: printf("请输入要删除的书籍名称: "); scanf("%s", deleteBook.title); pos = LocateElem(bookList, &deleteBook, CompareBook); if (pos != 0) { ListDelete(&bookList, pos, &deleteBook); printf("书籍删除成功!\n"); } else { printf("书籍不存在!\n"); } break; case 6: printf("请输入要修改的书籍ID: "); scanf("%d", &bookId); if (GetElem(bookList, bookId, &modifyBook) == OK) { printf("当前书籍信息: "); PrintBook(modifyBook); printf("请输入新的书名、作者和价格: "); scanf("%s%s%f", modifyBook.title, modifyBook.author, &modifyBook.price); ListDelete(&bookList, bookId, &modifyBook); ListInsert(&bookList, bookId, &modifyBook); printf("书籍信息修改成功!\n"); } else { printf("书籍不存在!\n"); } break; case 7: printf("书籍列表:\n"); for (int i = 1; i <= bookList.length; i++) { GetElem(bookList, i, &newBook); PrintBook(newBook); } break; case 8: printf("请输入要购买的书籍ID: "); scanf("%d", &bookId); if (GetElem(bookList, bookId, &newBook) == OK && newBook.status == 0) { printf("请输入用户ID: "); scanf("%d", &userId); GetElem(userList, userId, &loginUser); if (loginUser.balance >= newBook.price) { loginUser.balance -= newBook.price; ListDelete(&bookList, bookId, &newBook); newBook.status = 1; ListInsert(&bookList, bookId, &newBook); ListDelete(&userList, userId, &loginUser); ListInsert(&userList, userId, &loginUser); printf("购买成功!\n"); } else { printf("余额不足!\n"); } } else { printf("书籍不存在或已售出!\n"); } break; case 9: printf("请输入要查询余额的用户ID: "); scanf("%d", &userId); if (GetElem(userList, userId, &loginUser) == OK) { printf("余额: %.2f\n", loginUser.balance); } else { printf("用户不存在!\n"); } break; case 10: printf("请输入用户ID和充值金额: "); scanf("%d%f", &userId, &amount); if (GetElem(userList, userId, &loginUser) == OK) { loginUser.balance += amount; ListDelete(&userList, userId, &loginUser); ListInsert(&userList, userId, &loginUser); printf("充值成功!\n"); } else { printf("用户不存在!\n"); } break; case 11: printf("所有用户信息:\n"); for (int i = 1; i <= userList.length; i++) { GetElem(userList, i, &newUser); PrintUser(newUser); } break; case 12: SaveData(userList, bookList); printf("数据导出成功!\n"); break; case 13: SaveData(userList, bookList); DestroyList(&userList); DestroyList(&bookList); printf("系统已退出,数据已保存。\n"); exit(0); default: printf("无效的选择! 请重试.\n"); } } } int main() { MainMenu(); return 0; }在每次 scanf 后调用 getchar(),确保缓冲区中的残留字符被清除。
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值