如何在不使用scanf()
的情况下将用户指定的整数和浮点值分配给变量或数组?
就像getchar
和fgetc
fgets
,char
,string
...等,是否有浮点数和整数的函数?< / p>
答案 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);
}
}