期中考试后我做完了这个学期的pta题目,得意忘形,用pta中的题目打趣老师,没想到老师在下节课上增加了题目。这题对我来说是颇有难度的一道题,完整代码在文章结尾。
这道题要求我们识别出输入语句中的宏定义,处理语句中的多余空格并将其中的宏替换。
处理语句还有额外要求:语句前的空格与双引号内的内容不能改动。
任务貌似有点多,让我们稍微拆分下。
考虑到宏的输入会有“ #define hehe "hehe"”这样的形式,按照以下顺序来进行或许更方便:
1.读取输入的语句
2.识别是否有宏
3.移除宏语句的多余空格并读取其中的宏
4.对其他语句替换宏
5.移除多余空格
6.打印结果
框架
题目规定不会在预编译语句外出现'#'!这是个好消息,我们可以依靠这个识别预编译语句。
题目要求引号内不做处理,我们可以设置状态变量quote,如果不在引号内,quote为0,否则为1。
对于第3-5步,我们暂时没有明显的思路,故可以将其中可能会用到的操作声明为函数,方便我们调试。
为了确保宏的有关数据有序,我们用结构体数组来存储宏。
typedef struct {//包含标识符与宏字符串的结构体
char name[21];
char value[31];
} Def;
Def def[10];//结构体数组
int def_count = 0;//已获取的宏数量
void remove_spaces(char* line);//移除空格
void remove_def_spaces(char* line);//移除宏语句空格
int get_def(char* line);//获取宏
void replace_def(char* line);//替换宏
int main(void) {
char line[201];//用于存储输入的c++语句
while (fgets(line, sizeof(line), stdin)) {//当读取一行语句
if (strchr(line, '#') != NULL) //如果在这条语句中含有字符'#'
if (get_def(line)) continue;//则获取其中的标识符与宏字符串
if (strcmp(line, "@@\n") == 0) break; //如果语句为@@,结束读取
replace_def(line);//替换其中的宏
remove_spaces(line);//移除多余的空格
if (strlen(line) > 0) printf("%s", line);//输出语句
}
return 0;
}
获取宏
要获取宏,我们可以识别"#define"来知道是否为宏语句,首先我们会对其移除一次多余空格。
处理空格与后面的步骤高度重合,所以假如我们读取到的都是正确格式,那么我们可以用sscanf函数来获取标识符与宏字符串,这个函数可以从字符串中读取输入。
为了保证读取到的宏合法,我们对