1. 程式人生 > >CCF CSP認證考試歷年真題 模板生成系統 C語言實現

CCF CSP認證考試歷年真題 模板生成系統 C語言實現

試題編號:201509-3
試題名稱:日期計算 時間限制:1.0s 記憶體限制:256.0MB

問題描述:

成成最近在搭建一個網站,其中一些頁面的部分內容來自資料庫中不同的資料記錄,但是頁面的基本結構是相同的。例如,對於展示使用者資訊的頁面,當用戶為 Tom 時,網頁的原始碼是


而當用戶為Jerry 時,網頁的原始碼是



這樣的例子在包含動態內容的網站中還有很多。為了簡化生成網頁的工作,成成覺
得他需要引入一套模板生成系統。
  模板是包含特殊標記的文字。成成用到的模板只包含一種特殊標記,格式為 {{ VAR }},其中 VAR 是一個變數。該標記在模板生成時會被變數 VAR 的值所替代。例如,如果變數 name = "Tom",則 {{ name }} 會生成 Tom。具體的規則如下:   ·變數名由大小寫字母、數字和下劃線 (_) 構成,且第一個字元不是數字,長度
不超過 16 個字元。
  ·變數名是大小寫敏感的,Name 和 name 是兩個不同的變數。
  ·變數的值是字串。
  ·如果標記中的變數沒有定義,則生成空串,相當於把標記從模板中刪除。   ·模板不遞迴生成。也就是說,如果變數的值中包含形如 {{ VAR }} 的內容,不
再做進一步的替換。
輸入格式
  輸入的第一行包含兩個整數 m, n,分別表示模板的行數和模板生成時給出的變數個數。 
  接下來 m 行,每行是一個字串,表示模板。 
  接下來 n 行,每行表示一個變數和它的值,中間用一個空格分隔。值是字串,用雙引號 (") 括起來,內容可包含除雙引號以外的任意可列印 ASCII 字元(ASCII 碼
範圍 32, 33, 35-126)。 
輸出格式 
  輸出包含若干行,表示模板生成的結果。 
樣例輸入 11 2 
<!DOCTYPE html> 
<html> <head> 
<title>User {{ name }}</title> 
</head> <body> 
<h1>{{ name }}</h1> 
<p>Email: <a href="mailto:{{ email }}">{{ email }}</a></p> 
<p>Address: {{ address }}</p> 
</body> </html> 
name "David Beckham" email "

[email protected]
樣例輸出 
<!DOCTYPE html> 
<html> <head> 
<title>User David Beckham</title> 
</head> <body> 
<h1>David Beckham</h1> 
<p>Email: <a href="mailto:[email protected]">[email protected]</a></p> 
<p>Address: </p> 
</body> </html> 
評測用例規模與約定   0 ≤ m ≤ 100   0 ≤ n ≤ 100 
  輸入的模板每行長度不超過 80 個字元(不包含換行符)。 
  輸入保證模板中所有以 {{ 開始的子串都是合法的標記,開始是兩個左大括號和一
個空格,然後是變數名,結尾是一個空格和兩個右大括號。 
  輸入中所有變數的值字串長度不超過 100 個字元(不包括雙引號)。 
  保證輸入的所有變數的名字各不相同。

分析:

題目本身邏輯不能,這題主要考驗對程式輸入,輸出,字串的運用。這裡我用C語言來寫,主要的scanf,printf的格式控制符的瞭解,這裡給出兩個不錯的連結:

http://blog.csdn.net/qingkong8832/article/details/6667701

http://blog.csdn.net/sdhfll/article/details/1892926

程式碼在此:

#include<stdio.h>
#include<string.h>

#define F_PATH "C:\\Users\\Administrator\\Desktop\\C\\data.txt"
#define ADDITION 10 //字串新增多餘空間防止溢位 

typedef struct{
	char value[80 + ADDITION];
}late;	// 一行模板 

typedef struct{
	char key[100 + ADDITION];
	char value[100 + ADDITION];
}variable;	// 一個變數 

int main()
{
	int m, n;
	late str[100 + ADDITION];
	variable var[100 + ADDITION];
	char ch;
	
	scanf("%d %d", &m, &n);
	
/*	while( (ch=getchar()) != '\n' )
		continue;*/
	ch = getchar();	// 必須加這個,因為%[]讀取時會把上一個\n給讀取到進去然後跳過直接空字串。不用ch = getchar();就得在上一個scanf()改成 scanf("%d %d\n", &m, &n)。又或者把ch = getchar();換成上面那個我while迴圈 
	for(int i = 0; i < m; i ++)
	{
		scanf("%[^\n]%*c", str[i].value);	//接收一行 
	}
	
	for(int i = 0; i < n; i ++)
	{

		scanf("%s %*c%[^\"]", var[i].key, var[i].value);
		scanf("%*c"); // %[^\"] 不會接收後面的\",不過\"還是在輸入快取中,在獲取變數的值後需要把這個\"從輸入快取中去掉以免影響下一次 
	}
	
	for(int i = 0; i < m; i ++)	//迴圈輸出m行模板 
	{
		int len = strlen(str[i].value);
		for(int j = 0; j < len; j ++)	//迴圈判斷沒行模板的每個字元 
		{
			if(str[i].value[j] == '{' && str[i].value[j+1] == '{')	//由於沒有巢狀,所有直接判斷即可 
			{
				char strtemp[100];
				j += 3;	//跳入模板變數區域
				int u = 0;
				while(str[i].value[j] != ' ')	//獲取模板裡的變數 
				{
					strtemp[u ++] = str[i].value[j];
					j ++;
				}
				for(int k = 0; k < n; k ++)	//查詢對應的變數替代輸出 
				{
					if(strcmp(strtemp, var[k].key) == 0)
					{
						printf("%s", var[k].value);
						break;
					}
				}
				j += 3;	//跳出模板變數區域 
			}
			else
			{
				printf("%c", str[i].value[j]);	//無需替換字元直接輸出 
			}
		}
		printf("\n"); 
	}
	
	return 0;
}