如何在c中使用`scanf()`得到整数和浮点输入?

时间:2017-08-04 17:11:09

标签: c floating-point int scanf

如何在不使用scanf()的情况下将用户指定的整数和浮点值分配给变量或数组?

就像getcharfgetc fgetscharstring ...等,是否有浮点数和整数的函数?< / p>

3 个答案:

答案 0 :(得分:2)

没有读取整数和浮点数的函数,但是你可以fgets使用strtol表示整数,strtof表示浮点数:

// floats:
char str_f[20];
float f;

fgets (str_f, 20, stdin);
f = strtof(str_f, NULL);

// integers:
char str_i[20];
int i;

fgets(str_i, 20, stdin);
i = strtol(str_i, NULL, 0);

您也可以使用atoi作为整数,但不推荐使用atoi,因为// floats: char *endptr_f; char str_f[20]; float f; fgets (str_f, 20, stdin); f = strtof(str_f, &endptr_f); if (*endptr_f != '\n' || str_f[0] == '\n' || endptr_f == str_f) { printf("ERROR: \"%s\" is an invalid float!\n", str_f); } // integers: char *endptr_i; char str_i[20]; int i; fgets(str_i, 20, stdin); i = strtol(str_i, &endptr_i, 0); if (*endptr_i != '\n' || str_i[0] == '\n' || endptr_i == str_i) { printf("ERROR: \"%s\" is an invalid integer!\n", str_i); } 没有检测到错误,而且它被认为是过时的。

如果要检测错误,可以使用以下代码:

{{1}}

答案 1 :(得分:0)

多年前我写过这篇文章,在VS2017中测试过,仍然有效。非常简单,不是很好,但也许你可以用它来做某事

#define INT_CONVERTED       (1 << 0)
#define FLOAT_CONVERTED     (1 << 1)

char *strlwr(char *str)
{
    char *ptr = str;

    while (*ptr)
    {
        *ptr = tolower(*ptr);
        ptr++;
    }
    return str;
}


int NumberOfDots(char *s)
{
    int dots = 0;
    while (*s)
        dots += *s++ == '.';
    return dots;
}

int NOTstrcasechr(char *str, int ch)
{
    return strchr(str, ch) == NULL && strchr(str, toupper(ch)) == NULL;
}

int ReadNumber(double *db, int *in)
{
    int result = 0;

    do
    {
        char str[100];
        int dots;

        result = 0;
        printf("Enter number: ");
        fgets(str, 100, stdin);
        if ((dots = NumberOfDots(str)) > 1) str[0] = '\0';

        if (sscanf(str, "%lf", db) == 1)
        {
            result |= FLOAT_CONVERTED;
        }
        if (!result || (!dots && NOTstrcasechr(str, 'e')))
            if (NOTstrcasechr(str, 'x'))
            {
                if (sscanf(str, "%d", in) == 1)
                {
                    result |= INT_CONVERTED;
                }
            }
            else 
                if(result)
                {
                    result |= INT_CONVERTED;
                    *in = (int)*db;
                }
        if (strstr(strlwr(str), "exit") != NULL) result = -1;

    } while (!result);
    return result;
}


int main(int argc, char **argv)
{
    double db;
    int in;
    int result;

    while ((result = ReadNumber(&db, &in)) != -1)
    {

        if (result & FLOAT_CONVERTED) printf("Float = %lf ", db);
        if (result & INT_CONVERTED) printf("Integer = %d ", in);
        printf("\n\r");

    }
    return 0;
}

Enter number: xfdsfdsfdsf
Enter number: rthdgfhghg
Enter number: 0x4567
Float = 17767.000000 Integer = 17767
Enter number: 3e67
Float = 30000000000000000978680950144401383192292617328216608963406365458432.000000
Enter number: 54567
Float = 54567.000000 Integer = 54567
Enter number: dfgdfgdfgdfgdgg
Enter number: 3456
Float = 3456.000000 Integer = 3456
Enter number: 12354654465454654654565567567576
Float = 12354654465454653961713368432640.000000 Integer = -1
Enter number: exit

答案 2 :(得分:-1)

  

是否有浮点数和整数的函数?

是的,它是scanf(),但OP不想使用它。

  

如何在没有scanf()的情况下获取整数和浮动输入?

scanf("%d", &some_int)scanf("%f", &some_float)一样,这不是一项微不足道的任务。

主要问题是一旦消耗了最长的有效输入就停止读取字符 - 这可能位于一行用户输入的中间。我没有找到一个简洁的强大解决方案。

相反,改变了为一个整数long读取用户输入的的问题。阅读float是类似的。需要在***行附近进行更改

仍然存在有限文本长度的问题。以下代码假定有效输入最多为打印long所需的最大值的2倍。

溢出是一个在某种程度上解决的问题。回想一下scanf(),OF / UF是未定义的行为。

中心思想是通过跳过空格,读取N个字符然后在此之后查找任何非空白区域来读取一行。然后解析缓冲区。

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// character array size needed to represent all `long`
#define INT_STR_SIZE (sizeof(long)*CHAR_BIT/3 + 3)
#define INT_BUF_SIZE (INT_STR_SIZE*2)

int readline_long(long *dest) {                        // ***
  int ch;
  while (isspace(ch = getchar()) && ch != '\n') {
    ;
  }
  if (ch == EOF) return EOF;
  ungetc(ch, stdin);

  char buf[INT_BUF_SIZE];                                 // ***
  if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;
  if (strchr(buf, '\n') == NULL) {
    // Get rest of line
    bool only_white_space = true;
    while ((ch = getchar()) != '\n' && ch != EOF) {
      if (!isspace(ch)) only_white_space = false; // consume rest of line
    }
    if (!only_white_space) return 0;  // extra junk
  }
  char *endptr;
  errno = 0;
  long y = strtol(buf, &endptr, 10);                    // ***
  if (buf == endptr) return false;  // no conversion
  while (isspace((unsigned char) *endptr)) {
    endptr++;
  }
  if (*endptr) return 0; // extra junk
  *dest = y;
  return 1;
}

测试代码

int main(void) {
  long lg;
  int retval;
  while ((retval = readline_long(&lg)) != EOF) {
    printf("retval = %d", retval);
    if (retval > 0) printf(" val = %ld", lg);
    if (errno) printf(" errno = %d", errno);
    putchar('\n');
    fflush(stdout);
  }
}