提问人:Alexander Jonsson 提问时间:6/16/2023 更新时间:6/16/2023 访问量:63
使用返回的字符串和 malloc 确定输入是否仅为数字或 q
determine if input is only digits or q using a returned string and malloc
问:
我想创建自己的函数,在其中输入输入,然后我的函数将确定我是只输入数字(例如 23412)还是只输入单个 q。其他所有内容都应计为无效输入。请注意,“242q42”、“5435q”或“qq”应被视为无效输入。我相信我设法创建了一个工作函数,可以决定我是否只输入数字,但我不确定我应该怎么做才能让 q 的东西正常工作。这是我的代码(如果您看到错误或低效的代码或我可以进行的其他改进,请发表评论):
char *readLine(int nr) {
int ch, i=0;
char *string;
string = malloc(nr);
while((ch = getchar()) != '\n') {
if(i<nr && isdigit(ch)!=0) {
string[i++]=ch;
}
else {
string=NULL;
return string;
}
}
string[i]='\0';
return string;
}
int main(void) {
int number;
printf("Enter number: ");
char *p=readLine(100);
if(p==NULL) {
printf("Invalid input!\n");
}
else {
number=atoi(p);
printf("Number as int is %d ", number);
}
free(p);
return 0;
}
答:
添加另一个检查为第一个字符的语句,并将其添加到 .if
q
string
在分配之前,您还需要这样做,否则会出现内存泄漏。free(string)
NULL
在呼叫者中,在尝试呼叫之前检查 。q
atoi()
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
char *readLine(int nr) {
int ch, i=0, q_entered = 0;
char *string;
string = malloc(nr);
while((ch = getchar()) != '\n') {
if(i<nr && !q_entered && isdigit(ch)!=0) {
string[i++]=ch;
} else if (i == 0 && ch == 'q') {
string[i++] = ch;
q_entered = 1;
} else {
free(string);
return NULL;
}
}
string[i]='\0';
return string;
}
int main(void) {
int number;
printf("Enter number: ");
char *p=readLine(100);
if(p==NULL) {
printf("Invalid input!\n");
} else if (strcmp(p, "q") == 0) {
printf("Quitting\n");
} else {
number=atoi(p);
printf("Number as int is %d\n", number);
}
free(p);
return 0;
}
也就是说,通常更好的设计是将输入代码与解析输入的代码分开。 应该只以任何格式返回该行,并且您应该有一个单独的函数来检查这一点。readLine()
allDigits()
评论
q
"0"
if (number == 0)
同时检查“q”,您的代码将如下所示:
char *readLine(int nr) {
int ch, i=0;
char *string;
string = malloc(nr);
while((ch = getchar()) != '\n') {
if(i<nr && isdigit(ch)!=0) {
string[i++]=ch;
}
else if (ch=='q' && i==0 && getchar()=='\n')
{
string[i++]=ch;
return string;
}
else {
string=NULL;
return string;
}
}
string[i]='\0';
return string;
}
int main(void) {
int number;
printf("Enter a number or q: ");
char *p=readLine(100);
if(p==NULL) {
printf("Invalid input!\n");
}
else if (p[0]=='q' && p[1]=='\0')
{
printf("You entered q\n");
}
else {
number=atoi(p);
printf("Number as int is %d ", number);
}
free(p);
return 0;
}
在您的问题中,您表示您希望输入包含以下任一内容
- 仅数字,或
- 只有单个字符.
"q"
否则,输入无效,应被拒绝。
但是,在评论部分,您指出输入字符串也应该被拒绝。相反,您希望输入在某个最大值的范围内。"0"
1
在这种情况下,使用该函数来确定输入是否有效是没有意义的,因为它会将该输入报告为有效,尽管您希望该输入被拒绝为无效。isdigit
"0"
出于这个原因,我建议您首先使用函数 fgets
读取整行,然后检查该行的内容。如果该行由单个字符组成,则您知道输入有效。否则,您可以使用函数 strtol
尝试将输入转换为整数。q
如果此转换失败,那么您将知道输入无效。
但是,如果转换成功,则可以执行进一步的检查,以确定转换后的整数是否在所需范围内,例如,它是否在 的范围内。1
20
下面是一个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#define MIN_INPUT_NUMBER 1
#define MAX_INPUT_NUMBER 20
void get_line_from_user( const char prompt[], char buffer[], int buffer_size );
int main( void )
{
char line[200], *p;
long num;
//read exactly one line of input from the user
get_line_from_user(
"Please enter a number: ",
line, sizeof line
);
//determine whether the user entered `"q"` as input
if ( line[0] == 'q' && line[1] == '\0' )
{
printf( "Input is valid, user entered \"q\".\n" );
exit( EXIT_SUCCESS );
}
//attempt to convert input to a number
errno = 0;
num = strtol( line, &p, 10 );
//verify that at least one character was converted
if ( p == line )
{
printf( "Error: Unable to convert input to integer!\n" );
exit( EXIT_FAILURE );
}
//verify that input is not too small or too large to be
//representable as a `long int`
if ( errno == ERANGE )
{
printf( "Error: Input is outside the range of a long int!\n" );
exit( EXIT_FAILURE );
}
//verify that either all characters were converted or that all
//remaining characters are whitespace characters, so that input
//such as "242q42" gets rejected
for ( ; *p != '\0'; p++ )
{
if ( !isspace( (unsigned char)*p ) )
{
printf( "Error: Not all non-whitespace characters were converted!\n" );
exit( EXIT_FAILURE );
}
}
//verify that the converted integer is in the desired range
if ( num < MIN_INPUT_NUMBER || num > MAX_INPUT_NUMBER )
{
printf(
"Error: Input must be in the range %d to %d.\n",
MIN_INPUT_NUMBER, MAX_INPUT_NUMBER
);
exit( EXIT_FAILURE );
}
//everything went ok, so print the result
printf( "Input was valid! User entered %ld.\n", num );
return EXIT_SUCCESS;
}
//This function will read exactly one line of input from the
//user. It will remove the newline character, if it exists. If
//the line is too long to fit in the buffer, then the function
//will automatically reprompt the user for input. On failure,
//the function will never return, but will print an error
//message and call "exit" instead.
void get_line_from_user( const char prompt[], char buffer[], int buffer_size )
{
for (;;) //infinite loop, equivalent to while(1)
{
char *p;
//prompt user for input
fputs( prompt, stdout );
//attempt to read one line of input
if ( fgets( buffer, buffer_size, stdin ) == NULL )
{
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
//attempt to find newline character
p = strchr( buffer, '\n' );
//make sure that entire line was read in (i.e. that
//the buffer was not too small to store the entire line)
if ( p == NULL )
{
int c;
//a missing newline character is ok if the next
//character is a newline character or if we have
//reached end-of-file (for example if the input is
//being piped from a file or if the user enters
//end-of-file in the terminal itself)
if ( (c=getchar()) != '\n' && !feof(stdin) )
{
if ( c == EOF )
{
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
printf( "Input was too long to fit in buffer!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
//this error message will be printed if either
//a stream error or an unexpected end-of-file
//is encountered
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
} while ( c != '\n' );
//reprompt user for input by restarting loop
continue;
}
}
else
{
//remove newline character by overwriting it with
//null character
*p = '\0';
}
//input was ok, so break out of loop
break;
}
}
此程序具有以下行为:
Please enter a number: 242q42
Error: Not all non-whitespace characters were converted!
Please enter a number: 5435q
Error: Not all non-whitespace characters were converted!
Please enter a number: qq
Error: Unable to convert input to integer!
Please enter a number: q
Input is valid, user entered "q".
Please enter a number: 50000000000000000000000000
Error: Input is outside the range of a long int!
Please enter a number: -23
Error: Input must be in the range 1 to 20.
Please enter a number: 0
Error: Input must be in the range 1 to 20.
Please enter a number: 22
Error: Input must be in the range 1 to 20.
Please enter a number: 17
Input was valid! User entered 17.
为了更改允许的范围,您可以更改线
#define MIN_INPUT_NUMBER 1
#define MAX_INPUT_NUMBER 20
在程序中。
下一个:Malloc 字符数组。字符串
评论
q
-23
-
+23
+
+23