14.1 示例问题:创建图书目录
处理一本书, 书名-作者-价格, 输入输出 book.c–一本书的图书目录
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* s_gets(char* st, int n);
#define MAXTITL 41
#define MAXAUTL 31
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library;
printf("Please enter the book title.\n");
s_gets(library.title, MAXTITL);
printf("Now enter the author.\n");
s_gets(library.author, MAXAUTL);
printf("Now enter the value.\n");
scanf("%f", &library.value);
printf("%s by %s: $%.2f\n", library.title, library.author, library.value);
printf("%s: \"%s\" ($%.2f)\n", library.title, library.author, library.value);
printf("Done.\n");
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n')
{
continue;
}
}
}
return ret_val;
}
14.2 结构数组
处理多本书,输入输出。 manybook.c–包含多本书的图书目录
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* s_gets(char* st, int n);
#define MAXTITL 41
#define MAXAUTL 31
#define MAXBKS 100
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index;
printf("Please enter the book title.\n");
printf("Press [enter] at the start of a line to stop.\n");
while (count < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL
&& library[count].title[0] != '\0')
{
printf("Now enter the author.\n");
s_gets(library[count].author, MAXAUTL);
printf("Now enter the value.\n");
scanf("%f", &library[count++].value);
while (getchar() != '\n') {
continue;
}
if (count < MAXBKS) {
printf("Enter the next title.\n");
}
}
if (count > 0) {
printf("Here is the list of your books:\n");
for (index = 0; index < count; index++) {
printf("%s by %s: $%.2f\n", library[index].title,
library[index].author, library[index].value);
}
}
else {
printf("No books? Too bad.\n");
}
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n')
{
continue;
}
}
}
return ret_val;
}
14.5 嵌套结构
在一个结构中包含另一个结构(即嵌套结构)很方便。 friend.c–嵌套结构示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define LEN 20
const char* msgs[5] = {
" Thank you for the wonderful evening, ",
"You certainly prove that a ",
"is a special kind of guy. We must get together",
"over a delicious ",
" and have a few laughs"
};
struct name {
char first[LEN];
char last[LEN];
};
struct guy {
struct name handle;
char favfood[LEN];
char job[LEN];
float income;
};
int main(void)
{
struct guy fellows = {
{"Ewen" , "Villard"},
"grilled salmon",
"personality coach",
68112.00
};
printf("Dear %s,\n\n", fellows.handle.first);
printf("%s%s.\n", msgs[0], fellows.handle.first);
printf("%s%s\n", msgs[1], fellows.job);
printf("%s\n", msgs[2]);
printf("%s%s%s", msgs[3], fellows.favfood, msgs[4]);
if (fellows.income > 1500000.0f) {
printf("!!");
}
else if (fellows.income > 75000.0f) {
printf("!");
}
else {
printf(".");
}
printf("\n%40s%s\n", " ", "See you soon,");
printf("%40s%s\n", " ", "Shalala");
return 0;
}
14.6 指向结构的指针
演示:如何定义指向结构的指针和如何用这样的指针访问结构的成员 friends.c–使用指向结构的指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#define LEN 20
struct name {
char first[LEN];
char last[LEN];
};
struct guy {
struct name handle;
char favfood[LEN];
char job[LEN];
float income;
};
int main(void)
{
struct guy fellows[2] = {
{
{"Ewen", "Villard"},
"grilled salmon",
"personality coach",
68112.00
},
{
{"Rodney", "Swillbelly"},
"tripe",
"tabloid editor",
432400.00
}
};
struct guy* him;
printf("address #1: %p #2: %p\n", &fellows[0], &fellows[1]);
him = &fellows[0];
printf("address #1: %p #2: %p\n", him, him + 1);
printf("him->income is $%.2f: (*him).income is $%.2f\n", him->income, (*him).income);
him++;
printf("him->favfood is %s: (*him).favfood is %s\n", him->favfood, (*him).favfood);
return 0;
}
14.7 向函数传递结构的信息
传递结构成员
funds.c–把结构成员作为参数传递
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#define FUNDLEN 50
struct funds {
char bank[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(double x, double y);
int main(void)
{
struct funds stan = {
"Garlic-Melon Bank",
4032.27,
"Lucky's Saving and Loan",
8543.94
};
printf("Stan has a total of $%.2f.\n",
sum(stan.bankfund, stan.savefund));
return 0;
}
double sum(double x, double y)
{
return (x + y);
}
传递结构地址
funds2.c–传递指向结构的指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#define FUNDLEN 50
struct funds {
char bank[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(const struct funds*);
int main(void)
{
struct funds stan = {
"Garlic-Melon Bank",
4032.27,
"Lucky's Saving and Loan",
8543.94
};
printf("Stan has a total of $%.2f.\n",
sum(&stan));
return 0;
}
double sum(const struct funds *money)
{
return (money->bankfund + money->savefund);
}
传递结构
funds3.c–传递一个结构
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#define FUNDLEN 50
struct funds {
char bank[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(struct funds moolah);
int main(void)
{
struct funds stan = {
"Garlic-Melon Bank",
4032.27,
"Lucky's Saving and Loan",
8543.94
};
printf("Stan has a total of $%.2f.\n", sum(stan));
return 0;
}
double sum( struct funds moolah)
{
return (moolah.bankfund + moolah.savefund);
}
14.7.4 其它结构特性
names1.c–使用指向结构的指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define NLEN 30
struct namect {
char fname[NLEN];
char lname[NLEN];
int letters;
};
void getinfo(struct namect *);
void makeinfo(struct namect *);
void showinfo(const struct namect *);
char* s_gets(char* st, int n);
int main(void)
{
struct namect person;
getinfo(&person);
makeinfo(&person);
showinfo(&person);
return 0;
}
void getinfo(struct namect* pst)
{
printf("Please enter your first name.\n");
s_gets(pst->fname, NLEN);
printf("Please enter your last name.\n");
s_gets(pst->lname, NLEN);
}
void makeinfo(struct namect* pst)
{
pst->letters = strlen(pst->fname) + strlen(pst->lname);
}
void showinfo(const struct namect* pst)
{
printf("%s %s, your name contains %d letters.\n",
pst->fname, pst->lname, pst->letters);
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n') {
continue;
}
}
}
return ret_val;
}
如何使用结构参数和返回来完成相同的任务
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define NLEN 30
struct namect {
char fname[NLEN];
char lname[NLEN];
int letters;
};
struct namect getinfo(void);
struct namect makeinfo(struct namect );
void showinfo(struct namect);
char* s_gets(char* st, int n);
int main(void)
{
struct namect person;
person = getinfo();
person = makeinfo(person);
showinfo(person);
return 0;
}
struct namect getinfo(void)
{
struct namect temp;
printf("Please enter your first name.\n");
s_gets(temp.fname, NLEN);
printf("Please enter your last name.\n");
s_gets(temp.lname, NLEN);
return temp;
}
struct namect makeinfo(struct namect info)
{
info.letters = strlen(info.fname) + strlen(info.lname);
return info;
}
void showinfo(const struct namect info)
{
printf("%s %s, your name contains %d letters.\n",
info.fname, info.lname, info.letters);
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n') {
continue;
}
}
}
return ret_val;
}
14.7.7 结构、指针和malloc()
name3.c–使用指针和malloc()
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SLEN 81
struct namect {
char * fname;
char * lname;
int letters;
};
void getinfo(struct namect *);
void makeinfo(struct namect *);
void showinfo(const struct namect *);
char* s_gets(char* st, int n);
void cleanup(struct namect*);
int main(void)
{
struct namect person;
getinfo(&person);
makeinfo(&person);
showinfo(&person);
return 0;
}
void getinfo(struct namect * pst)
{
char temp[SLEN];
printf("Please enter your first name.\n");
s_gets(temp, SLEN);
pst->fname = (char*)malloc(strlen(temp) + 1);
strcpy(pst->fname, temp);
printf("Please enter your last name.\n");
s_gets(temp, SLEN);
pst->lname = (char*)malloc(strlen(temp) + 1);
strcpy(pst->lname, temp);
}
void makeinfo(struct namect * info)
{
info->letters = strlen(info->fname) + strlen(info->lname);
}
void showinfo(const struct namect * info)
{
printf("%s %s, your name contains %d letters.\n",
info->fname, info->lname, info->letters);
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n') {
continue;
}
}
}
return ret_val;
}
void cleanup(struct namect* pst)
{
free(pst->fname);
free(pst->lname);
}
14.7.8 复合字面量和结构
complit.c–复合字面量
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXTITL 41
#define MAXAUTL 31
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book readfirst;
int score;
printf("Enter test score: ");
scanf("%d", &score);
if (score >= 84) {
readfirst = (struct book){ "Crime and Punishment",
"Fyodor Dostoyevsky",
12.25f };
}
else {
readfirst = (struct book){ "Mr. Bouncy's Nice Hat",
"Fred Winsome",
5.99f };
}
printf("Your assigned reading:\n");
printf("%s by %s: $%.2f\n", readfirst.title,
readfirst.author, readfirst.value);
return 0;
}
14.7.11 使用结构数组的函数
funds4.c–把结构数组传递给函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FUNDLEN 50
#define N 2
struct funds {
char bank[FUNDLEN];
double bankfunds;
char save[FUNDLEN];
double savefunds;
};
double sum(const struct funds money[], int n);
int main(void)
{
struct funds jones[N] = {
{
"Garlic-Melon Bank",
4032.27,
"Lucky's Savings and Loan",
8543.94,
},
{
"Honest Jack's Bank",
3620.88,
"Party Time Savings",
3802.91,
}
};
printf("The Jones have a total of $%.2f.\n", sum(jones, N));
return 0;
}
double sum(const struct funds money[], int n)
{
double total;
int i;
for (i = 0, total = 0; i < n; i++) {
total += money[i].bankfunds + money[i].savefunds;
}
return (total);
}
14.8 把结构内容保存到文件中
使用fread()和fwrite()函数读写结构大小的单元 保存结构的程序示例 把书名保存到book.dat文件中,如果该文件已经存在,程序将显示它当前的内容,然后允许在文件中添加内容。 booksave.c–在文件中保存结构中的内容
14.11.4 enum的用法
enum.c–使用枚举类型的值
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* s_gets(char* st, int n);
enum spectrum {red, orange, yellow, green, blue, violet};
const char* colors[] = { "red", "orange", "yellow", "green", "blue", "violet" };
#define LEN 30
int main(void)
{
char choice[LEN];
enum spectrum color;
bool color_is_found = false;
puts("Enter a color (enter line to quit):");
while (s_gets(choice, LEN) != NULL && choice[0] != '\0') {
for (color = red; color <= violet; color++) {
if (strcmp(choice, colors[color]) == 0) {
color_is_found = true;
break;
}
}
if (color_is_found) {
switch (color) {
case red: puts("Rose are red.");
break;
case orange: puts("Poppies are orange.");
break;
case yellow: puts("Sunflowers are yellow.");
break;
case green: puts("Grass is green.");
break;
case blue: puts("Blubells are blue.");
break;
case violet: puts("Violets are violet.");
break;
}
}
else {
printf("I don't know about the color %s.\n", choice);
}
color_is_found = false;
puts("Nest color, please (empty line to quit):");
}
puts("Goodbye!");
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\0') {
continue;
}
}
}
return ret_val;
}
14.14 函数和指针
func_ptr.c–使用函数指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define LEN 81
char* s_gets(char* st, int n);
char showmenu(void);
void eatline(void);
void show(void(*fp)(char*), char* str);
void ToUpper(char*);
void ToLower(char*);
void Transpose(char*);
void Dummy(char*);
int main(void)
{
char line[LEN];
char copy[LEN];
char choice;
void (*pfun)(char*) = NULL;
puts("Enter a string (empty line to quit):");
while (s_gets(line, LEN) != NULL && line[0] != '\0') {
while ((choice = showmenu()) != 'n') {
switch (choice) {
case 'u': pfun = ToUpper; break;
case 'l': pfun = ToLower; break;
case 't': pfun = Transpose; break;
case 'o': pfun = Dummy; break;
}
strcpy(copy, line);
show(pfun, copy);
}
puts("Enter a string (empty line to quit):");
}
puts("Bye!");
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\0') {
continue;
}
}
}
return ret_val;
}
char showmenu(void)
{
char ans;
puts("Enter menu choice:");
puts("u) uppercase l) lowercase");
puts("t) transposed case o) original case");
puts("n) next string");
ans = getchar();
ans = tolower(ans);
eatline();
while (strchr("ulton", ans) == NULL) {
puts("Please enter a u, l, t, o, or n:");
ans = tolower(getchar());
eatline();
}
return ans;
}
void eatline(void)
{
while (getchar() != '\n') {
continue;
}
}
void show(void(*fp)(char*), char* str)
{
(*fp)(str);
puts(str);
}
void ToUpper(char* str)
{
while(*str) {
*str = toupper(*str);
str++;
}
}
void ToLower(char* str)
{
while(*str) {
*str = tolower(*str);
str++;
}
}
void Transpose(char* str)
{
while(*str) {
if (islower(*str)) {
*str = toupper(*str);
}
else if(isupper(*str)) {
*str = tolower(*str);
}
str++;
}
}
void Dummy(char* str)
{
}
|