C语言 我如何使我的字符串在这个程序中的开关内部工作?

vh0rcniy  于 2023-05-28  发布在  其他
关注(0)|答案(3)|浏览(222)

我正在尝试编写一个代码,它确实选择了一个int数或一个char,在一个字符串中,如果我的输入是一个char bettewen A和D,则显示我的年龄范围选项,如果我选择了一个年龄,则显示类。我是插入所有在一个大开关的情况下,但当我到“情况10:”简单的输入dosent工作,我没有看到使它工作。有关代码:

#include <stdio.h>

int main(){
    
    char resp[300];
    
    printf ("Inform the letter of the class\nOr the age of the student\n");
    scanf (" %s", &resp[300]);
    
    switch (resp[300]){
        
        case 'a':
        case 'A':
        printf ("\nFor students in the class A\nThe age range is between 4~5 years.");
        break;
        
        case 'b':
        case 'B':
        printf ("\nFor students in the class B\nThe age range is between 6~8 years.");
        break;
        
        case 'c':
        case 'C':
        printf ("\nFor students in the class C\nThe age range is between 9~10 years.");
        break;
        
        case '4' ... '5':
        printf ("\nFor the students in the age %s\nThe class will be A.", resp);   
        break;
        
        case '6' ... '8':
        printf ("\nFor the students in the age %s\nThe class will be B.", resp);
        break;
        
        case '9':
        case 10:
        printf ("\nFor the students in the age %s\nThe class will be C.", resp);
        break;
        
        default:
        printf ("\nWe are out of class\nFor students below 4 yo\nOr more than 10yo.");
        break;
        
    }
    return 0; 
}

当我们得到值10时,代码简单地忽略了这种情况并结束程序,并且程序没有正确地显示4-9之间的字符串,有什么方法可以让开关工作吗?
我试着做一个条件,如果值是10,就转换它:

if (resp[300] == "10"){
resp [300] = x;}

并将case "10":切换为case 'x':。但这并不能使事情正常进行。

voj3qocg

voj3qocg1#

char resp[300];

这声明了一个300个元素的char数组。由于字符串需要以零结尾,因此最多可以容纳299个字符。

scanf (" %s", &resp[300]);

应该是scanf( " %s", resp )。或者,更好的是scanf( " %299s", resp ),以避免溢出。
你应该始终检查scanf()及其兄弟的返回值。如果输入失败,则resp将未初始化。

switch (resp[300])

这将访问resp301 st元素(因为编号从0开始)。此元素不存在,访问是未定义的行为。如果你想要数组的最后一个元素,你可以使用resp[299],但这也不是你想要的。如果你想要 string 的最后一个字符,你可以使用resp[ strlen( resp ) - 1 ],但这也不是你想要的。
您实际需要的是 * 第一个 * 字符,即resp[0]

case '6' ... '8':

除非你使用的是某种扩展语言,否则这根本不起作用; C没有...运算符。

case 10:

这不是你想的那样相反,它将字符的 binary 表示与 value 10进行比较。在ASCII中,这将是换行符。
总而言之,关于用户输入的强烈建议是使用fgets()来读取输入的 * 整行 *,然后在内存中解析它们(例如:使用strtol()strcmp()或类似物)。强烈不鼓励在可能格式错误的用户输入上使用*scanf(); *scanf()是用来读取已知良好的数据的,它从错误中正常恢复的能力是有限的。switch是不同的值。它不适用于范围,而且对于一般的字符串处理来说也是相当不合适的。

qlzsbp2j

qlzsbp2j2#

从你们所有人那里得到一些反馈,并做了一些研究,我用以下方式对我的问题提出了一个相当简单的解决方案:

#include <stdio.h>
#include <ctype.h>

int main() {

    char resp[30];
    int i;
    
    
    printf ("Inform the letter of the class\nOr the age of the student\n");
    scanf(" %s", resp);
    
    for (i = 0; resp[i] != '\0'; i++) { 
        if (!isalpha(resp[i])) { 
            break; 
        }
    }
    
    if (resp[i] != '\0') {//if the value of [i] is different of null the result must be in the range of a char.
        int num = atoi(resp);//then i convert the string number to a int num
        
        switch (num){
        
        case 4:    
        case 5:
        printf ("\nFor the students in the age %i\nThe class will be A.", num);   
        break;
        
        case 6:
        case 7:
        case 8:
        printf ("\nFor the students in the age %i\nThe class will be B.", num);
        break;
        
        case 9:
        case 10:
        printf ("\nFor the students in the age %i\nThe class will be C.", num);
        break;
        
        default:
        printf ("\nWe are out of class\nFor students below 4 yo\nOr more than 10yo.");
        break;
        
        }
    
    }
    else {//if the value [i] is null the result must be a char.
        
        switch (resp[0]){
            
        case 'a':
        case 'A':
        printf ("\nFor students in the class A\nThe age range is between 4~5 years.");
        break;
        
        case 'b':
        case 'B':
        printf ("\nFor students in the class B\nThe age range is between 6~8 years.");
        break;
        
        case 'c':
        case 'C':
        printf ("\nFor students in the class C\nThe age range is between 9~10 years.");
        break;
        
        default:
        printf ("\nInvalid Class.");
    
        }
    }
    return 0;
}
42fyovps

42fyovps3#

其中一个答案已经列出并解释了代码中的错误。
因此,在这个答案中,我只会向你展示我将如何解决这个问题的代码:

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

//forward declarations
void get_line_from_user( const char prompt[], char buffer[], int buffer_size );
bool convert_string_to_long( char str[], long *num );

int main( void )
{
    //repeat until input is valid
    for (;;)
    {
        char input[300];
        long num;

        //get input from user
        get_line_from_user(
            "Please enter the letter of the class or the age of the student: ",
            input, sizeof input
        );

        //determine whether the user entered an integer
        if ( convert_string_to_long( input, &num ) )
        {
            switch( num )
            {
                case 4:
                case 5:
                    printf( "For the students of the age %ld, the class will be A.", num );
                    break;
                case 6:
                case 7:
                case 8:
                    printf( "For the students of the age %ld, the class will be B.", num );
                    break;
                case 9:
                case 10:
                    printf( "For the students of the age %ld, the class will be C.", num );
                    break;
                default:
                    printf( "Invalid age! It must be between 4 and 10!\n" );
                    continue;
            }

            //input was ok, so break out of infinite loop
            break;
        }
        else
        {
            if ( input[0] == '\0' )
            {
                //input is empty, so reprompt user for input without
                //printing an error message
                continue;
            }
            if ( input[1] != '\0' )
            {
                //make sure that there are no further characters
                //after the first one, or that all superfluous
                //characters are whitespace characters
                for ( int i = 1; input[i] != '\0'; i++ )
                {
                    if ( !isspace( (unsigned char)input[i] ) )
                    {
                        printf( "Input must be an integer or a single letter!\n" );

                        //we cannot use "continue" here, because
                        //that would go to the next iteration of the
                        //inner loop, but we want to instead go to
                        //the next iteration of the outer loop
                        goto continue_outer_loop;
                    }
                }

                //the following block is only intended as a goto
                //target for jumping out of the nested loop
                if ( false )
                {
continue_outer_loop:
                    continue;
                }
            }

            switch ( toupper( (unsigned char)input[0] ) )
            {
                case 'A':
                    printf ("For students in class A, the age range is between 4-5 years.");
                    break;
                case 'B':
                    printf ("For students in class B, the age range is between 6-8 years.");
                    break;
                case 'C':
                    printf ("For students in class C, the age range is between 9-10 years.");
                    break;
                default:
                    printf( "Invalid letter!\n" );
                    continue;
            }
        }

        //input was ok, so break out of the infinite loop
        break;
    }
    
    return 0;
}

//This function will return true if the entire string was
//successfully converted to a long integer, otherwise it will
//return false.
bool convert_string_to_long( char str[], long *num )
{
    long result;
    char *p;

    //attempt to convert string to number
    result = strtol( str, &p, 10 );
    if ( p == str )
    {
        return false;
    }

    //verify that there are no unconverted characters, or that if
    //such characters do exist, that they are all whitespace
    //characters
    for ( ; *p != '\0'; p++ )
    {
        if ( !isspace( (unsigned char)*p ) )
        {
            return false;
        }
    }

    //everything went ok, so pass the result
    *num = result;
    return true;
}

//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 ( ferror(stdin) )
                {
                    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 ( ferror(stdin) )
                    {
                        printf( "Error reading from input!\n" );
                        exit( EXIT_FAILURE );
                    }

                } while ( c != '\n' && c != EOF );

                //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 the letter of the class or the age of the student: abc
Input must be an integer or a single letter!
Please enter the letter of the class or the age of the student: 6abc
Input must be an integer or a single letter!
Please enter the letter of the class or the age of the student: 3
Invalid age! It must be between 4 and 10!
Please enter the letter of the class or the age of the student: 4
For the students of the age 4, the class will be A.
Please enter the letter of the class or the age of the student: d
Invalid letter!
Please enter the letter of the class or the age of the student: b
For students in class B, the age range is between 6-8 years.

正如你所看到的,我设计了这样一个程序,它将检查输入是否有效,如果不是,它将自动重新提示用户进行新的输入。

相关问题