为了账号安全,请及时绑定邮箱和手机立即绑定

c-canf()vs get()vs fget()

c-canf()vs get()vs fget()

C
慕无忌1623718 2019-10-12 16:07:54
c-canf()vs get()vs fget()我一直在做一个相当简单的程序,将字符串(假设输入了数字)转换为Integer。在我做完之后,我注意到一些我无法回答的非常奇怪的“bug”,主要是因为我对scanf(), gets()和fgets()功能起作用。(不过,我确实读过很多文献。)因此,在不写太多文字的情况下,下面是程序的代码:#include <stdio.h>#define MAX 100int CharToInt(const char *);int main(){     char str[MAX];     printf(" Enter some numbers (no spaces): ");     gets(str);//  fgets(str, sizeof(str), stdin);//  scanf("%s", str);     printf(" Entered number is: %d\n", CharToInt(str));     return 0;}int CharToInt(const char *s){     int i, result, temp;     result = 0;     i = 0;     while(*(s+i) != '\0')     {         temp = *(s+i) & 15;         result = (temp + result) * 10;         i++;     }     return result / 10;}这就是我一直面临的问题。首先,当使用gets()功能,程序工作得很完美。第二,当使用fgets(),结果有点错误,因为很明显fgets()函数最后读取换行符(ASCII值10),这会导致结果混乱。第三,当使用scanf()函数,结果是完全错误的,因为第一个字符显然有一个-52的ASCII值.对此,我没有任何解释。现在我知道了gets()不鼓励使用,所以我想知道我是否可以使用fgets()在这里,它不会读取(或忽略)换行符。还有,那是怎么回事scanf()在这个程序中起作用?
查看完整描述

3 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

  • 绝不可能使用gets..它不提供针对缓冲区溢出漏洞的保护(也就是说,您不能告诉它您传递给它的缓冲区有多大,因此它不能阻止用户进入大于缓冲区的行并破坏内存)。

  • 避免使用scanf..如果不小心使用,它可能会出现与以下相同的缓冲区溢出问题:gets..即使忽略了这一点,它还有其他问题,使它很难正确使用。.

  • 通常您应该使用fgets相反,尽管有时很不方便(您必须去掉换行符,您必须提前确定缓冲区大小,然后您必须弄清楚如何处理太长的行-您是否保留了所读的部分和丢弃多余的,丢弃整件事,动态增长缓冲区,然后再试一次,等等)。有一些非标准的函数可以为您执行这种动态分配。getline关于POSIX系统,查克·法尔科纳的公共领域ggets职能)。请注意ggetsgets-就像语义学一样,它为你剥去了一个尾随的换行符。



查看完整回答
反对 回复 2019-10-13
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

是的,你想避免getsfgets将始终读取新行,如果缓冲区足够大,足以容纳它(这会让您知道缓冲区太小,并且有更多的行等待读取)。如果你想要fgets它不会读取新行(丢失太小缓冲区的指示),您可以使用fscanf具有如下的扫描集转换:"%N[^\n]",其中‘N’替换为缓冲区大小-1。

在读取完后,一种简单(如果奇怪)方法可以从缓冲区中删除拖尾的新行。fgets是:strtok(buffer, "\n");不是这样的strtok是打算被使用的,但我用这种方式比以预期的方式使用它的频率要高(我通常避免使用这种方式)。



查看完整回答
反对 回复 2019-10-13
  • 3 回答
  • 0 关注
  • 314 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信