C - scanf() vs gets() vs fgets() [英] C - scanf() vs gets() vs fgets()

查看:19
本文介绍了C - scanf() vs gets() vs fgets()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在做一个相当简单的程序,将一串字符(假设输入了数字)转换为一个整数.

I've been doing a fairly easy program of converting a string of Characters (assuming numbers are entered) to an Integer.

完成后,我注意到一些我无法回答的非常奇特的错误",主要是因为我对 scanf()gets()fgets() 函数有效.(不过我确实阅读了很多文献.)

After I was done, I noticed some very peculiar "bugs" that I can't answer, mostly because of my limited knowledge of how the scanf(), gets() and fgets() functions work. (I did read a lot of literature though.)

所以不用写太多文字,这里是程序的代码:

So without writing too much text, here's the code of the program:

#include <stdio.h>

#define MAX 100

int 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
", CharToInt(str));

    return 0;
}

int CharToInt(const char *s)
{
    int i, result, temp;

    result = 0;
    i = 0;

    while(*(s+i) != '')
    {
        temp = *(s+i) & 15;
        result = (temp + result) * 10;
        i++;
    }

    return result / 10;
}

这就是我一直遇到的问题.首先,当使用gets()函数时,程序运行良好.

So here's the problem I've been having. First, when using gets() function, the program works perfectly.

第二,当使用fgets()时,结果有点错误,因为显然fgets()函数最后读取换行符(ASCII值10),结果搞砸了.

Second, when using fgets(), the result is slightly wrong because apparently fgets() function reads newline (ASCII value 10) character last which screws up the result.

第三,当使用scanf() 函数时,结果完全错误,因为第一个字符显然有-52 ASCII 值.对此,我没有任何解释.

Third, when using scanf() function, the result is completely wrong because first character apparently has a -52 ASCII value. For this, I have no explanation.

现在我知道不鼓励使用 gets(),所以我想知道我是否可以在这里使用 fgets() 这样它就不会读取 (或忽略)换行符.另外,这个程序中的 scanf() 函数是怎么回事?

Now I know that gets() is discouraged to use, so I would like to know if I can use fgets() here so it doesn't read (or ignores) newline character. Also, what's the deal with the scanf() function in this program?

推荐答案

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

    • Never use gets. It offers no protections against a buffer overflow vulnerability (that is, you cannot tell it how big the buffer you pass to it is, so it cannot prevent a user from entering a line larger than the buffer and clobbering memory).

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

      Avoid using scanf. If not used carefully, it can have the same buffer overflow problems as gets. Even ignoring that, it has other problems that make it hard to use correctly.

      通常应该使用 fgets 代替,虽然有时不方便(你必须去掉换行符,你必须提前确定缓冲区大小,然后你必须弄清楚要做什么)处理太长的行–你是否保留你阅读的部分并丢弃多余的部分,丢弃整个内容,动态增加缓冲区并重试,等等).有一些非标准函数可以为您进行动态分配(例如,POSIX 系统上的 getlineChuck Falconer 的公共域ggets 函数).请注意,ggets 具有类似 gets 的语义,因为它为您去除了尾随换行符.

      Generally you should use fgets instead, although it's sometimes inconvenient (you have to strip the newline, you must determine a buffer size ahead of time, and then you must figure out what to do with lines that are too long–do you keep the part you read and discard the excess, discard the whole thing, dynamically grow the buffer and try again, etc.). There are some non-standard functions available that do this dynamic allocation for you (e.g. getline on POSIX systems, Chuck Falconer's public domain ggets function). Note that ggets has gets-like semantics in that it strips a trailing newline for you.

      这篇关于C - scanf() vs gets() vs fgets()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆