我目前只能做一小部分作业。 分配的一项要求是
“调用一个函数,该函数提示用户输入二次方程的系数a,b和c的每个值,并返回输入的值,并通过错误检查有效输入(scanf返回一个值)。”
,我不知道该怎么做。我可以轻松提示用户输入,也可以检查输入是否有效,但是我不知道如何将其转换为函数。我当前的代码是:
{
if (isalpha(a))
{
printf("INPUT ERROR!\n");
printf("Enter a value for a: ");
scanf("%d", &a);
}
} //this is how I would normally check the input
int main(void) //start of main() function definition
{
int a, b, c, n, D; //declares integer variables a, b, c, n, and D
float root1, root2; //declares float variables root1 and root2
do //do while loop starts here
{
printf("Enter a value for a: "); //prompts user to input integer for variable 'a'
scanf("%d", &a); //reads an integer from the keyboard and stores in the variable 'a'
printf("%d\n", a); //returns value of integer that was input for variable 'a'
printf("Enter a value for b: "); //prompts user to input integer for variable 'b'
scanf("%d", &b); //reads an integer from the keyboard and stores in the variable 'b'
printf("%d\n", b); //returns value of integer that was input for variable 'b'
printf("Enter a value for c: "); //prompts user to input integer for variable 'c'
scanf("%d", &c); //reads an integer from the keyboard and stores in the variable 'c'
printf("%d\n", c); //returns value of integer that was input for variable 'c'
...}
很抱歉出现任何格式错误,但这基本上是我坚持使用的程序的一部分。
我的问题是,如何将第一个函数与do / while循环中的所有内容组合在一起,以制作一个可以调用三次的大函数?
我不知道如何使用一个函数为a和b切换出a的所有实例,因为我以前从未真正使用过这样的函数。
答案 0 :(得分:3)
提示用户输入整数值并检查有效输入的功能
如果用户仅逐行输入有效的整数文本,则代码很简单:
// Overly idealized case
fputs(prompt, stdout);
char buf[50];
fgets(buf, sizeof buf, stdin);
int i = atoi(buf);
但是用户是good, bad and ugly,并且**发生了。如果代码要读取一行,对其进行解析以得到一个int
范围,并检测到许多问题,则下面的代码将审查许多典型的虚假和恶意输入问题。
我特别感兴趣的是检测到过长的输入是否具有敌意性,并且作为针对黑客的审慎设计而无效。如下所示,几乎没有理由允许有效输入超过20个字符的32位int
。这种理性值得更深入的解释。
首先使用fgets()
读取输入的行,然后应用各种int
验证测试。如果fgets()
没读完整行,则其余的读完。
#include <limits.h>
#include <ctype.h>
// Max number of `char` to print an `int` is about log10(int_bit_width)
// https://stackoverflow.com/a/44028031/2410359
#define LOG10_2_N 28
#define LOG10_2_D 93
#define INT_DEC_TEXT (1 /*sign*/ + (CHAR_BIT*sizeof(int)-1)*LOG10_2_N/LOG10_2_D + 1)
// Read a line and parse an integer
// Return:
// 1: Success
// 0: Failure
// EOF: End-of-file or stream input error
int my_get_int(int *i) {
// Make room for twice the expected need. This allows for some
// leading/trailing spaces, leading zeros, etc.
// int \n \0
char buf[(INT_DEC_TEXT + 1 + 1) * 2];
if (fgets(buf, sizeof buf, stdin) == NULL) {
*i = 0;
return EOF; // Input is either at end-of-file or a rare input error.
}
int success = 1;
char *endptr;
errno = 0;
long value = strtol(buf, &endptr, 10);
// When `int` is narrower than `long`, add these tests
#if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
if (value < INT_MIN) {
value = INT_MIN;
errno = ERANGE;
} else if (value > INT_MAX) {
value = INT_MAX;
errno = ERANGE;
}
#endif
*i = (int) value;
if (errno == ERANGE) {
success = 0; // Overflow
}
if (buf == endptr) {
success = 0; // No conversion
}
// Tolerate trailing white-space
// Proper use of `is...()` obliges a `char` get converted to `unsigned char`.
while (isspace((unsigned char ) *endptr)) {
endptr++;
}
// Check for trailing non-white-space
if (*endptr) {
success = 0; // Extra junk
while (*endptr) { // quietly get rest of buffer
endptr++;
}
}
// Was the entire line read?
// Was the null character at the buffer end and the prior wasn't \n?
const size_t last_index = sizeof buf / sizeof buf[0] - 1;
if (endptr == &buf[last_index] && buf[last_index - 1] != '\n') {
// Input is hostile as it is excessively long.
success = 0; // Line too long
// Consume text up to end-of-line
int ch;
while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
;
}
}
return success;
}
样品用量
puts("Enter a value for a: ", stdout);
fflush(stdout); // Insure output is seen before input.
int a;
if (my_get_int(&a) == 1) {
printf("a:%d\n", a);
}
答案 1 :(得分:2)
我的问题是,如何将第一个函数与do / while循环中的所有内容组合在一起,以制作一个可以调用三次的大函数?
嗯,功能不必很大。需要考虑的因素是提示字符串和要读取的变量-后者可以留在调用main()
中并从返回值分配。关于如何您通常会检查输入,我建议将此检查留给scanf()
并仅测试其返回值。
#include <stdio.h>
#include <stdlib.h>
int input(char *prompt)
{ // prompts user to input integer
// reads an integer from standard input and returns it
int a, s; // leave it to scanf to check the input:
while (printf("%s", prompt), fflush(stdout), s = scanf("%d", &a), !s)
{
printf("INPUT ERROR!\n");
do s = getchar(); while (s != '\n' && s != EOF); // consume bad input
}
if (s == EOF) puts(""), exit(0); // no more input
return a;
}
然后您可以在main()
中做
a = input("Enter a value for a: ");
b = input("Enter a value for b: ");
c = input("Enter a value for c: ");
(无循环)。
答案 2 :(得分:1)
scanf()
已经根据格式说明符(%d
)为您处理了输入,因此您只需要了解scanf
的工作原理并使用它来检查和构建您的功能:)
当您写scanf("%d", &a);
时,程序会因为%d
的说明而希望写一个整数,如果读取了整数,程序会将其写到变量a
中。
但是函数scanf
也有一个返回值,即,您可以执行check = scanf("%d", &a);
,在这种情况下,check
的值为0或1。这是因为返回值记录了已成功读取了多少个值。如果输入dsfugnodg
,则没有数字,因此它将返回0。如果输入659 32
,它将成功读取第一个值并返回1。
您的函数将类似于:
#include <stdio.h>
int getAndPrint(char label)
{
int n = 0, val = 0;
do {
printf("Enter a value for %c: ", label);
n = scanf("%d", &val);
if (n == 0) {
printf("Error, invalid value entered.\n");
/* Consume whatever character leads the wrong input
* to prevent an infinite loop. See:
* https://stackoverflow.com/questions/1669821/scanf-skips-every-other-while-loop-in-c */
getchar();
}
} while (n == 0);
printf("%c = %d\n", label, val);
return val;
}
int main()
{
int a, b, c;
a = getAndPrint('a');
b = getAndPrint('b');
c = getAndPrint('c');
printf("a=%d, b=%d, c=%d\n", a, b, c);
}
答案 3 :(得分:0)
我认为您需要以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // for isalpha
void InputAndCheck(int * pValue, const char * pName)
{
do
{
printf("Enter a value for %s: ", pName);
scanf("%d", pValue);
if (isalpha(*pValue))
{
printf("INPUT ERROR!\n");
continue;
}
else
{
break;
}
} while (1);
// clear the input buffer
fflush(stdin);
return;
}
int main()
{
int a, b, c;
InputAndCheck(&a, "a");
InputAndCheck(&b, "b");
InputAndCheck(&c, "c");
printf("a=%d;b=%d;c=%d;\r\n",a,b,c);
return 0;
}
答案 4 :(得分:-2)
您正在寻找的是功能介绍。 这是一个:https://www.tutorialspoint.com/cprogramming/c_functions.htm
这是编程中非常重要的构建基块,您绝对应该学习掌握这一概念。
函数将允许您反复在不同的上下文中执行一些代码,而只需更改上下文(参数)即可。
像这样声明
int add(int first, int second){
//here we can use first and second
printf("first: %d\n", first);
printf("second: %d\n", second);
//and eventually return a value
return first+second;
}
现在,当使用我们的代码时,我们将重用以前的代码执行任务,结果根据所传递的参数而有所不同。
printf("1+2 = %d\n", add(1, 2));
-->3
printf("2+2 = %d\n", add(2, 2));
-->4
您的任务的示例解决方案:
//this will handle validation
int validateInput(int input){
if(isalpha(input)){
printf("INPUT ERROR!\n");
return 0;
}
return 1;
}
//this will prompt the user and return input only if the input is valid
int askForCoefficient(unsigned char coefficientName){
int valid = 0;
int value = 0;
while(!valid){
printf("Enter a value for %c: ", coefficientName);
value = scanf("%d", &value);
valid = validateInput(value);
}
printf("%d\n", value);
return value;
}