猿问

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

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()在这个程序中起作用?



慕无忌1623718
浏览 315回答 3
3回答

慕哥6287543

绝不可能使用gets..它不提供针对缓冲区溢出漏洞的保护(也就是说,您不能告诉它您传递给它的缓冲区有多大,因此它不能阻止用户进入大于缓冲区的行并破坏内存)。避免使用scanf..如果不小心使用,它可能会出现与以下相同的缓冲区溢出问题:gets..即使忽略了这一点,它还有其他问题,使它很难正确使用。.通常您应该使用fgets相反,尽管有时很不方便(您必须去掉换行符,您必须提前确定缓冲区大小,然后您必须弄清楚如何处理太长的行-您是否保留了所读的部分和丢弃多余的,丢弃整件事,动态增长缓冲区,然后再试一次,等等)。有一些非标准的函数可以为您执行这种动态分配。getline关于POSIX系统,查克·法尔科纳的公共领域ggets职能)。请注意ggets有gets-就像语义学一样,它为你剥去了一个尾随的换行符。

摇曳的蔷薇

是的,你想避免gets.&nbsp;fgets将始终读取新行,如果缓冲区足够大,足以容纳它(这会让您知道缓冲区太小,并且有更多的行等待读取)。如果你想要fgets它不会读取新行(丢失太小缓冲区的指示),您可以使用fscanf具有如下的扫描集转换:"%N[^\n]",其中‘N’替换为缓冲区大小-1。在读取完后,一种简单(如果奇怪)方法可以从缓冲区中删除拖尾的新行。fgets是:strtok(buffer, "\n");不是这样的strtok是打算被使用的,但我用这种方式比以预期的方式使用它的频率要高(我通常避免使用这种方式)。
随时随地看视频慕课网APP
我要回答