我使用gcc在Ubuntu 4.6.1和4.6.2 SUSE使用以下命令未定義的引用gets_s?
gcc gets_s.c
我的源代碼是
// Read and Display Lines
// gets_s.c
#include <stdio.h>
int main(void)
{
char first_name[11];
char last_name[11];
printf("First Name : ");
gets_s(first_name, 11);
printf("Last Name : ");
gets_s(last_name, 11);
puts(first_name);
puts(last_name);
return 0;
}
在闡述我的問題:
主要對我來說問題是線路輸入和線路保存之間的一一對應關係。
成功之後,fgets和gets_s之間的區別在於fgets包含了換行符終止符,而gets_s用空終止符替換了換行符終止符,以便保持行輸入和成功調用gets_s之間的一一對應關係。
對於溢出緩衝區長度的輸入,fgets接受適合緩衝區的字符數,並將剩餘的字符留在下一個fgets的輸入緩衝區中。
標準(K.3.5.4.1)規定,使用gets_s(與gets不同)需要在n-1個字符內換行符,EOF或讀取錯誤。因此溢出是一個運行時約束衝突。如果存在運行時約束衝突,則將緩衝區中的第一個字符設置爲空字符,並讀取並丟棄stdin輸入緩衝區中的字符,直到讀取換行符爲止,則會發生文件結束或發生讀取錯誤。
因此成功,我預計:
>fgets
First Name : Chris
Last Name : Szalwinski
Chris
Szalwinski
>
>gets_s
First Name : Chris
Last Name : Szalwinski
Chris
Szalwinski
>
溢出時,我預計從fgets和gets_s不同的行爲。換句話說,
>fgets
First Name : Christopher
Last Name : Christophe
r
>
>gets_s
First Name : Christopher
Last Name : Szalwinski
Szalwinski
>
注意我如何期望gets_s刪除第一行輸入的內容。
如果主要問題是線路輸入和線路之間的一個一一對應保存,在調試時重要的是,我們仍然需要寫我們自己的函數(類似的K &的r函數getline)
char *gets_s(char *s, int n)
{
int i, c;
for (i = 0; i < n - 1 && (c = getchar()) != EOF && c != (int)'\n'; i++)
s[i] = c;
s[i] = '\0';
while (n > 1 && c != EOF && c != (int)'\n')
c = getchar();
return c != EOF ? s : NULL;
}
通過這種功能可以保持一對一的對應關係,緩衝區爲 飽和,並且不存在運行時約束衝突。
我在得出這個結論時是否正確。
@Vlad:'gets'完全沒用。這就是C11將其徹底清除的原因。 – 2013-03-01 02:26:13
我剛剛嘗試過'-std = c11';它仍然沒有找到'gets_s'。並且'get_s'和C11附件K的其餘部分「邊界檢查接口」是* optional *,即使完全符合C11的實現(gcc還沒有)。一個實現可以定義宏__STDC_LIB_EXT1__並提供接口 - 或者不。 – 2013-03-01 02:45:54
所以,基本上,使用'fgets'。 – nneonneo 2013-03-01 02:55:29