开篇
本篇文章的问题来源为《编程珠玑》第3章其中一个问题,格式信函编程。说白了就是先在文件中定义一个文本模版,然后使用数据库中的数据去填充这个模版,最后得到填充后的文本,并输出。
问题概要
在常去的网店键入你的名字和密码并成功登录以后,弹出的下一页网页类似这样:
Welcome back,Jane!
We hope that you and all the members
of the Public family are constantly
reminding your neighbors there
on Maple Street to shop with us.
AS usual,we will ship your order to
Ms. Jane Q. public
600 Maple Street
Your Town, Iowa 12345
…
作为程序员,你会意识到隐藏在这一幕之后所发生的事情——计算机在数据库中查找你的用户名并返回如下所示的字段:
Public|Jane|Q|Ms.|600|Maple Street|Your Town|Iowa|12345但是,程序如何依据你的个人数据库记录来构建这个定制的网页呢?急躁的程序员可能会试图按照下面所示的方式开始编写程序:
read lastname, firstname, init, title, streetnum,
streetname, tomn, state, zip
print “Welcome back,”,firstname, “!”
print “We hope that you and all the members”
print “of the”, lastname, “family are constantly”
print “reminding your neighbous there”
print “on”, streetname, "to shop with us. "
print “As usual, we will ship your order to”
print " ",title, firstname, init “.”, lastname
print " ", streetnum, streetname
print " ", town “,”, state, zip
…一个更巧妙的方法是编写一个格式信函发生器(form letter generator)。该发生器基于下面所示的格式信函模板(form letter schema):
Welcome back, $1!
We hope that you and all the members
of the $0 family are constantly
reminding your neighbors there
on $5 to shop with us.
As usual, we will ship your order to
$3 $1 $2. $0
$4 $5
$6, $7 8... 符号 8 ... 符号 8...符号i代表记录中的第i个字段。于是, 0 代表姓,等等。模板使用下面的伪代码来解释。在伪代码中,文字符号 0代表姓,等等。模板使用下面的伪代码来解释。在伪代码中,文字符号 0代表姓,等等。模板使用下面的伪代码来解释。在伪代码中,文字符号在输入模板中记为$$。read fields from database
loop from start to end of schema
c = next character in schema
if c ! =‘ ′ p r i n t c h a r c e l s e c = n e x t c h a r a c t e r i n s c h e m a c a s e c o f ′ ' printchar c else c = next character in schema case c of ' ′printcharcelsec=nextcharacterinschemacasecof′’: printchar ‘$’
‘0’ - ‘9’: printstring field[c]
default: error(“bad schema”)
思路分析
上面的问题是书中的原文,简单来说就是,实现一个需求,可以将从后端取到的数据,填充到实现定义好的文本模版中。
这个问题的思路相对来说比较简单:
- 从文件中读取模版,判断是否为$
- 若不是 , 则直接输出;若为 ,则直接输出;若为 ,则直接输出;若为,则继续判断它的下一个字符,若它的下一个字符为数字,则以该数字为索引,取出对应数组中的元素,并输出
所谓代码即语言,请直接看我的代码实现。
代码实现
模版内容
// t.txt
Welcome back, $1!
We hope that you and all the members
of the $0 family are constantly
reminding your neighbors there
on $5 to shop with us.
As usual, we will ship your order to
$3 $1 $2. $0
$4 $5
$6, $7 $8
...
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 1024
int main() {
// 模拟从数据库读取到的数据
char* fields[] = {"Public", "Jane", "Q", "Ms.", "600", "Maple Street", "Your Town", "Iowa", "12345"};
int i;
// 打开文件
FILE *file = fopen("t.txt", "r");
if (!file) {
perror("打开文件失败!");
return EXIT_FAILURE;
}
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), file)) {
size_t len = strlen(line);
if (line[len - 1] == '\n') line[len - 1] = '\0'; // 去除换行符
for (i = 0; line[i] != '\0'; i++) {
if (line[i] == '$') {
i++;
if (line[i] == '$') {
printf("$");
} else if (line[i] >= '0' && line[i] <= '9') {
int index = line[i] - '0';
if (index >= 0 && index < sizeof(fields)/sizeof(fields[0])) {
printf("%s", fields[index]);
} else {
printf("error: 超出边界\n");
return EXIT_FAILURE;
}
} else {
fprintf(stderr, "error: 格式错误\n");
return EXIT_FAILURE;
}
} else {
putchar(line[i]);
}
}
putchar('\n');
}
fclose(file);
return EXIT_SUCCESS;
}
结果截图
注
以上便是使用C语言实现格式信函编程的思路,希望对您能有所帮助!
因个人能力有限,若代码有任何谬误的地方,还请不吝指正!愿我们共同在IT之路上向前狂奔。
感谢阅读!