gets()
的代码段
int main(int argc, char *argv[])
{
char str[MAX_SIZE]
gets(str);
printf("\n");
puts()
的代码段
printf("The most probable key is: %d\n", max2);
puts(output);
return 0;
我没有粘贴我的整个代码,因为这似乎与我的问题无关。我只是想知道一种解决此问题的方法,因为当我通过GCC运行代码时,它会给我带来错误,并且不允许我使用gets()
。我该如何解决?
答案 0 :(得分:4)
请改用fgets
和fputs
。除了消除gets
的所有缺陷外,gets
和fgets
之间在用法上还有一个主要区别:fgets
在缓冲区中存储换行符(并且gets
不会)。
因此,等效项-即,如果不需要,则删除任何新行-如下所示。函数调用strcspn(buffer,"\n")
给出最长的字符序列,直到遇到新行为止(如果字符串不包含新行,则为strlen(buffer))。通过向该位置的索引写入0
,可以消除新行-如果有的话。
char buffer[MAX_SIZE] = "";
if (fgets(buffer, MAX_SIZE ,stdin)) {
buffer[strcspn(buffer,"\n")] = '\0';
}
答案 1 :(得分:3)
您绝对应该绝对避免使用gets()
,its dangerous,并将其从最新的C
标准中删除。 That's why you see the warning
C11
,前言中提到了第6段
与上一版相比的主要变化包括:
[....]
- 删除了
gets
函数(<stdio.h>
)
相反,请使用fgets()
.
要补充一点,puts()
很好,我认为没有理由更换它。
答案 2 :(得分:1)
请勿使用gets()
。因为无法不知道数据就无法知道gets()
将读取多少个字符,并且由于gets()
将继续存储超过缓冲区末尾的字符,所以使用它非常危险。它已被用来破坏计算机的安全性。
改用fgets()
char * fgets ( char * str, int num, FILE * stream );
以下example显示了fgets()
函数的用法。
#include <stdio.h>
int main () {
FILE *fp;
char str[60];
/* opening file for reading */
fp = fopen("file.txt" , "r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
if( fgets (str, 60, fp)!=NULL ) {
/* writing content to stdout */
puts(str);
}
fclose(fp);
return(0);
}
答案 3 :(得分:0)
读取我可以使用替代方法来代替gets()
char str[MAX_SIZE]; gets()
个字符的行时, N
有问题。 (N
也算为'\n'
)。
当N > MAX_SIZE
时,结果为未定义行为(UB)。输入过多,无处可去。此UB通常会写入其他对象使用的位置。不好-很好。
C11消除了gets()
,从那以后就不再是标准功能。
@Stephan Lechner很好地建议了通常的fgets()
解决方案。 fgets()
以下列出了一些不足之处。
str[MAX_SIZE]
现在需要为str[MAX_SIZE + 1]
,因为fgets()
还保存了'\n'
,与gets()
不同。有时加+ 1不可行。
fgets()
保留电位 '\n'
。参见Removing trailing newline character from fgets()
当输入过多时,fgets()
根本不读取它,与gets()
不同。行为良好(不是UB),但我们仍然遇到这个问题:如何检测到过多的输入以及如何处理?
如果代码可以与这些代码一起使用,请使用fgets()
。否则,请继续阅读。
mygets()
替代
此功能的大小不需要为s
缓冲区的+1。
输入过长会返回NULL
。读取所有行。 s
缓冲区充满了初始字符。
char *mygets(char *s, size_t n) {
char *dest = s;
// Pathological case of n==0
char dummy[1];
if (n == 0) {
n = sizeof dummy;
dest = dummy;
}
size_t i = 0;
int ch;
n--;
while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
if (i < n) {
dest[i++] = (char) ch;
} else {
s = NULL; // Not enough room
}
}
if (ch == EOF) {
if (feof(stdin)) { // end-of-file
if (i == 0) {
s = NULL;
}
} else { // input error
i = 0;
s = NULL;
}
}
dest[i] = '\0';
return s;
}
微妙的奖励:
s
缓冲区在罕见的输入错误时定义良好。然后使用gets/fgets
缓冲区内容是不确定的。
0的病理大小已明确定义。 fgets()
有点iffy。
缓冲区大小是惯用的size_t
,而不是int
,就像fgets()
一样。
用法
str[MAX_SIZE];
if (mygets(str, sizeof str)) {
printf("Success <%s>\n", str);
} else {
if (feof(str)) printf("End of file detected. <%s>\n", str);
else if (ferror(str)) printf("End of file detected. <%s>\n", str);
else printf("Input too long <%s>.", str);
}