一道關於程式設計思想的經典題

2021-07-23 09:20:37 字數 1745 閱讀 2195

問題:乙個前後臺(linux +win32)共用的函式,函式實現的功能為拼裝乙個sql,如果我們想把它改為安全函式,如何改呢?

void makesqlstring(int a,int b,char *sqlstring)

int len =sprintf(sqlstring,「update tablea set a=%d 」,a);

if(b==0)

sprintf(sqlstring+len,「where b1=%d 」,b);

else

sprintf(sqlstring+len,「where b2=%d 」,b);

補充:大家都知道使用snprintf函式安全,但是有多少人了解其背後的陷阱?

【參考】:

這是一位20年老碼農的給我們新人上課時問的乙個問題,由於自己現在不是做c/c++的,對這塊不是特別清楚,就特地學習了一下。

sprintf()函式用於字串格式化,把格式化的資料寫入某個字串緩衝區。由於sprintf()沒法指定長度,所以某種程度上來說不夠安全,如今如果使用高版本的visual studio編譯器的話,會發出警告:使用sprintf存在風險,建議使用sprintf_s。不過sprintf_s是微軟的私有函式,考慮跨平台的話,肯定是不會用的。一般就是使用其公升級版snprintf函式啦。

snprintf()可以認為是sprintf()的公升級版,比sprintf()多了乙個引數,能夠控制要寫入的字串的長度,更加安全,只要稍加留意,不會造成緩衝區的溢位:

函式原型:

int

snprintf(char *str, size_t size, const

char *format, ...);

size 的作用就是限制往str寫入不超過size個位元組(包括了結尾的』\0』)。

因為sprintf()函式如果成功的話,返回成功寫入的位元組數(字元數),我就一直以為snprintf()函式也是如此,也就是snprintf()函式不會返回大於size的整數。

snprintf()並不是標c中規定的函式,但是在許多編譯器中,廠商提供了其實現的版本。

在gcc中,該函式名稱就snprintf(),而在vc中稱為_snprintf()。由於不是標準函式,沒有乙個統一的標準來規定該函式的行為,所以導致了各廠商間的實現版本可能會有差異。

差異發生在第二個引數size_t size(n)。在gcc中,引數n是要向str寫入3個字元,包括』\0』字元;在vc中,引數n是要寫入的字串的總字元數。下面有個兩個小例子:

//gcc下

int main()

結果是:

7 ab

//vc下

int main()

結果是:

-1 abc

從輸出結果可以知道:

gcc中的引數n表示向str中寫入n個字元,包括』\0』字元,並且返回實際的字串長度。

vc中的引數n表示會向str中寫入n個字元,不包括』\0』字元,並且不會在字串末尾新增』\0』符。當字串長度超過引數n時,函式返回-1,以表示可能導致錯誤。

【領悟】

這位老師的課算是我最喜歡的一門課,我個人認為前輩出這道的目的是告訴我們幾個道理:

1.程式開發是考驗智力,耐力,毅力的工作。在開發跨平台的**,是需要大量相容系問題,必須對**和機制本身有著充分的了解。

2.迷時師渡,悟時自渡,能憑藉各種力量解決問題。

一道程式設計題

題目要求 1 自己給定乙個集合 元數個數不得少於10個 2 讓使用者任一輸入乙個整數 3 根據使用者輸入的整數,移除集合中相應的元素 請根據示例找出元素移除的規律 4 運算結束後,集合中所有元素均被移除 示例 集合元素為 a b c d e f g h i j 使用者輸入的整數為 3 集合元素被移除...

一道程式設計題

程式設計愛好者論壇 有n個學生.每個學生都有自己的宗教信仰,可能相同,也可能不同。乙個調查機構想弄清楚宗教信仰的總數。但是,直接詢問可能會使人不快,於是,調查機構決定詢問m對學生,問他們是否具有相同的宗教信仰。如果相同,則他們會參加同一教會,彼此會認識 要求計算最大可能的宗教數。函式原型 int r...

另外一道關於Random的程式設計題

如果有1000個不同的數字,如何隨機取得其中的100個成為數列,並且數列中沒有重複。基本原理就是每次把這個數字exclude在外面。public static int get100randomnumberlist int random if random null random.length 100...