我正在尝试编写一个函数来从用户获取十进制输入并返回从ASCII转换的实际值。但是,该功能会导致跳过用户的下一个输入。如:中 输入输入:123
输入输入:/ * doesn;允许输入* /
输入输入:456
long sum = 0;
int character = fgetc(stdin);
while(character != '\n'){
if(character >= '0' && character <= '9'){
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
}
else{
/* reenter number */
}
character = fgetc(stdin);
}
return sum;
答案 0 :(得分:1)
来自评论:
stdin缓冲区中的额外换行符 ...
尝试使用以下格式字符串scanf()
替换当前方法:
char* fmt = "%[^\n]%*c";
它会读取换行符之前的所有内容,然后使用换行符。 *
是分配抑制器。
示例:(包括将输入字符串转换为float / integer数的函数)
float get_float(void);
long get_int(void);
int main(void)
{
float num_f = get_float();
long num_i = get_int();
return 0;
}
float get_float(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter floating point number and hit return:\n");
scanf(fmt, input);
return strtod(input, dummy);
}
long get_int(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter integer number and hit return:\n");
scanf(fmt, input);
return strtol(input, dummy, 10);
}
注意:这些函数很简单,说明了如何将输入转换为数字变量,并且没有任何错误或范围检查。正如评论者所述,在实施生产版本之前,您需要详细阅读 strtol() 和 strtof 。 (链接到Linux手册页,但因为这两个函数都是C标准库的一部分,所以也可以在 MSDN here 和 here )
答案 1 :(得分:1)
要弄清楚为什么你的代码不起作用,我建议你发布完整代码,因为问题可能在于你调用这个函数的方式。
所以在发布完整代码之前,我可以告诉你这个代码在我的机器上运行良好:
#include <stdio.h>
#include <ctype.h>
int getlong();
int main() {
printf("\t%d\n", getlong());
printf("\t%d\n", getlong());
return 0;
}
int getlong() {
long sum = 0;
int character = fgetc(stdin);
while (character != '\n') {
if (isdigit(character)) {
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
character = fgetc(stdin);
}
else {
character = fgetc(stdin);
continue;
}
}
return sum;
}
包含 ctype.h
是为了使用isdigit()
,同时告诉您字符是否为十进制数字。
但事实上,你不必自己做所有事情。使用标准库对您和计算机都更有效,更高效。
例如,您可以直接从stdin
扫描长整数:
#include <stdio.h>
int main() {
long value;
puts("Please input numbers:");
while (scanf(" %ld", &value) != 1) {
puts("Only numbers are welcome:");
scanf("%*[^\n]");
}
printf("%ld", value);
return 0;
}
注意format
开头的空格,这使得scanf()
丢弃所有提取的空格字符(包括空格,换行符和制表符),直到非空格字符为止满足。
或者,使用strtol()
,虽然比较少见:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buf[80];
char *pEnd;
long value;
do
{
puts("Numbers please:");
if (fgets(buf, 80, stdin) == NULL)
{
perror("fgets()");
return 1;
}
value = strtol(buf, &pEnd, 10);
}
while (*pEnd != '\n');
printf("%ld", value);
return 0;
}
当然,sscanf()
也可以,你可以自己编写代码。
答案 2 :(得分:0)
为什么不使用fgets
和sscanf
?
char buf[80];
float n;
if (fgets(buf, 80, stdin) != NULL) {
if (sscanf(buf, "%f", &n) == 1)
printf("%f\n", n);
else
fprintf(stderr, "invalid float\n");
}