如何使我的字符串在此程序的开关内正常工作?

huangapple go评论53阅读模式
英文:

How do i make my string work inside of the switch in this program?

问题

I am trying to make a code that does pick an int number or a char, inside a string and display my options of age range if my input is a char between A and D, and the class if I pick an age. I was inserting all in one big switch case, but when I get to the "case 10:", simply the input doesn't work, and I don't seem to make it work.
the code in question:

#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[0]);
    
    switch (resp[0]){
        
        case 'a':
        case 'A':
        printf ("\nFor students in class A\nThe age range is between 4~5 years.");
        break;
        
        case 'b':
        case 'B':
        printf ("\nFor students in class B\nThe age range is between 6~8 years.");
        break;
        
        case 'c':
        case 'C':
        printf ("\nFor students in class C\nThe age range is between 9~10 years.");
        break;
        
        case '4' ... '5':
        printf ("\nFor the students at age %c\nThe class will be A.", resp[0]);   
        break;
        
        case '6' ... '8':
        printf ("\nFor the students at age %c\nThe class will be B.", resp[0]);
        break;
        
        case '9':
        case '1':
        case '0':
        printf ("\nFor the students at age %c\nThe class will be C.", resp[0]);
        break;
        
        default:
        printf ("\nWe are out of class\nFor students below 4 yo\nOr more than 10yo.");
        break;
        
    }
    return 0; 
}

When we get to the value 10, the code simply ignores this case and ends the program, and the program does not properly display the strings in the cases between 4-9. Is there any way to make any of this work with the switch?

I tried to make a condition for it to convert if the value was 10 this way:

if (resp[0] == '10'){
    resp[0] = 'x';
}

and switch the case '10': for case 'x':, but this does not seem to make things work.

英文:

I am trying to make a code that does pick an int number or an char, inside on a string and display latter my options of age range if my input is an char bettewen A and D, and the class if i pick an age. I was inserting all in one big switch case but when i get to the "case 10:" simple the input dosent work, and i dont seen to make it work.
the code in question:

#include &lt;stdio.h&gt;

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

When we get to the value 10 the code simple ignores this case and end the program, and the program does nott proper display the strings in the cases bettwen 4-9, is there any way to make any of this work with the switch?

I try to make an condition for to it to convert if the value was 10 this way:

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

and switch the case &quot;10&quot;: for case &#39;x&#39;:.
but this does not seen to make things work.

答案1

得分: 4

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

应该更正为 scanf( "%s", resp )。或者更好的方式是 scanf( "%299s", resp ),以避免溢出。

你应该始终检查scanf()及其类似函数的返回值。如果输入失败,resp将不被初始化。

switch (resp[300]) 这段代码访问了 resp 的第301个元素(因为编号从0开始)。这个元素不存在,访问它将导致未定义的行为。如果你想要访问数组的最后一个元素,应该使用 resp[299],但这也不是你想要的。如果你想要访问字符串的最后一个字符,应该使用 resp[ strlen( resp ) - 1 ],但这也不是你想要的。实际上,你想要的是第一个字符,即 resp[0]

case '6' ... '8': 这段代码根本不起作用,除非你使用的是某种扩展语言;C语言没有 ... 运算符。

case 10: 这也不是你想要的效果。它实际上是将字符的二进制表示与 10 进行比较。在ASCII码中,这代表换行符。

总的来说,关于用户输入的强烈建议是使用 fgets() 来读取整行输入,然后在内存中解析它们(例如使用 strtol()strcmp() 或类似函数)。强烈不推荐在潜在的格式错误的用户输入上使用 *scanf()*scanf() 用于读取已知正确的数据,而且它很难从错误中优雅地恢复。而 switch 用于处理不同的值,对于处理字符串来说通常不合适。

英文:
char resp[300];

This declares a char array of 300 elements. As a string needs to be zero-terminated, this can hold up to 299 characters.

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

This should read scanf( &quot; %s&quot;, resp ). Or, better, scanf( &quot; %299s&quot;, resp ), to avoid overflow.

You should ALWAYS check the return value of scanf() and its brethren. If input failed, resp would be non-initialized.

switch (resp[300])

This accesses the 301st element of resp (as numbering starts with 0). This element does not exist, the access is undefined behavior. If you would want the last element of the array, you'd use resp[299], but that isn't what you want either. If you'd want the last character of the string, you'd use resp[ strlen( resp ) - 1 ], but that isn't what you want either.

What you actually want is the first character, which is resp[0].

case &#39;6&#39; ... &#39;8&#39;:

This does not work at all unless what you're using is some kind of extended language; C does not have a ... operator.

case 10:

This does not do what you think it does. Instead it compares a character's binary representation with the value 10. In ASCII, that would be the line feed.

All in all, the strong suggestion regarding user input is to use fgets() to read whole lines of input, and then parse them in memory (e.g. using strtol(), strcmp() or similar). Using *scanf() on potentially malformed user input is strongly discouraged; *scanf() is meant to read known good data, and its abilities to recover from error gracefully are limited. And switch is for distinct values. It does not work for ranges, and it is rather inadequate for working with strings in general.

答案2

得分: 1

以下是您提供的代码的中文翻译部分:

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

int main() {

    char resp[30];
    int i;
    
    printf ("请提供班级的字母\n或学生的年龄\n");
    scanf(" %s", resp);
    
    for (i = 0; resp[i] != '\0'; i++) { 
        if (!isalpha(resp[i])) { 
            break; 
        }
    }
    
    if (resp[i] != '\0') {//如果[i]的值不为空,结果必须在字符的范围内。
        int num = atoi(resp);//然后我将字符串数字转换为整数num
        
        switch (num){
        
        case 4:    
        case 5:
        printf ("\n对于年龄为 %i 的学生\n班级将是 A 班。", num);   
        break;
        
        case 6:
        case 7:
        case 8:
        printf ("\n对于年龄为 %i 的学生\n班级将是 B 班。", num);
        break;
        
        case 9:
        case 10:
        printf ("\n对于年龄为 %i 的学生\n班级将是 C 班。", num);
        break;
        
        default:
        printf ("\n我们没有班级\n适用于 4 岁以下的学生\n或 10 岁以上的学生。");
        break;
        
        }
    
    }
    else {//如果值[i]为空,结果必须是字符。
        
        switch (resp[0]){
            
        case 'a':
        case 'A':
        printf ("\n对于 A 班的学生\n年龄范围在 4~5 岁之间。");
        break;
        
        case 'b':
        case 'B':
        printf ("\n对于 B 班的学生\n年龄范围在 6~8 岁之间。");
        break;
        
        case 'c':
        case 'C':
        printf ("\n对于 C 班的学生\n年龄范围在 9~10 岁之间。");
        break;
        
        default:
        printf ("\n无效的班级。");
    
        }
    }
    return 0;
}

如果您需要进一步的帮助,请告诉我。

英文:

getting some feedback from all you guys, and doing some research i made a rather simple solution to my problem in the following way:

#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt;
int main() {
char resp[30];
int i;
printf (&quot;Inform the letter of the class\nOr the age of the student\n&quot;);
scanf(&quot; %s&quot;, resp);
for (i = 0; resp[i] != &#39;\0&#39;; i++) { 
if (!isalpha(resp[i])) { 
break; 
}
}
if (resp[i] != &#39;\0&#39;) {//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 (&quot;\nFor the students in the age %i\nThe class will be A.&quot;, num);   
break;
case 6:
case 7:
case 8:
printf (&quot;\nFor the students in the age %i\nThe class will be B.&quot;, num);
break;
case 9:
case 10:
printf (&quot;\nFor the students in the age %i\nThe class will be C.&quot;, num);
break;
default:
printf (&quot;\nWe are out of class\nFor students below 4 yo\nOr more than 10yo.&quot;);
break;
}
}
else {//if the value [i] is null the result must be a char.
switch (resp[0]){
case &#39;a&#39;:
case &#39;A&#39;:
printf (&quot;\nFor students in the class A\nThe age range is between 4~5 years.&quot;);
break;
case &#39;b&#39;:
case &#39;B&#39;:
printf (&quot;\nFor students in the class B\nThe age range is between 6~8 years.&quot;);
break;
case &#39;c&#39;:
case &#39;C&#39;:
printf (&quot;\nFor students in the class C\nThe age range is between 9~10 years.&quot;);
break;
default:
printf (&quot;\nInvalid Class.&quot;);
}
}
return 0;
}

答案3

得分: 0

以下是您的代码的翻译部分:

已经有其他回答列出并解释了您的代码中的错误。

因此,在这个答案中,我只会展示我将如何解决这个问题的代码:

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

//前向声明
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)
{
    //重复直到输入有效为止
    for (;;)
    {
        char input[300];
        long num;

        //从用户获取输入
        get_line_from_user(
            "请输入班级的字母或学生的年龄:",
            input, sizeof input
        );

        //确定用户是否输入整数
        if (convert_string_to_long(input, &num))
        {
            switch (num)
            {
                case 4:
                case 5:
                    printf("对于年龄为%ld的学生,班级将是A。\n", num);
                    break;
                case 6:
                case 7:
                case 8:
                    printf("对于年龄为%ld的学生,班级将是B。\n", num);
                    break;
                case 9:
                case 10:
                    printf("对于年龄为%ld的学生,班级将是C。\n", num);
                    break;
                default:
                    printf("无效的年龄!必须在4到10之间!\n");
                    continue;
            }

            //输入正确,跳出无限循环
            break;
        }
        else
        {
            if (input[0] == '\0')
            {
                //输入为空,重新提示用户输入而不打印错误消息
                continue;
            }
            if (input[1] != '\0')
            {
                //确保第一个字符后面没有进一步的字符,或者所有多余的字符都是空格字符
                for (int i = 1; input[i] != '\0'; i++)
                {
                    if (!isspace((unsigned char)input[i]))
                    {
                        printf("输入必须是整数或单个字母!\n");

                        //我们不能在这里使用"continue",因为
                        //那将进入内部循环的下一次迭代,但我们希望跳到
                        //外部循环的下一次迭代
                        goto continue_outer_loop;
                    }
                }

                //以下块仅用作跳出嵌套循环的跳转目标
                if (false)
                {
                    continue_outer_loop:
                        continue;
                }
            }

            switch (toupper((unsigned char)input[0]))
            {
                case 'A':
                    printf("对于A班的学生,年龄范围在4-5岁之间。\n");
                    break;
                case 'B':
                    printf("对于B班的学生,年龄范围在6-8岁之间。\n");
                    break;
                case 'C':
                    printf("对于C班的学生,年龄范围在9-10岁之间。\n");
                    break;
                default:
                    printf("无效的字母!\n");
                    continue;
            }
        }

        //输入正确,跳出无限循环
        break;
    }
    
    return 0;
}

//此函数将在整个字符串成功转换为长整数时返回true,否则将返回false。
bool convert_string_to_long(char str[], long *num)
{
    long result;
    char *p;

    //尝试将字符串转换为数字
    result = strtol(str, &p, 10);
    if (p == str)
    {
        return false;
    }

    //验证是否有未转换的字符,或者如果存在这样的字符,那么它们都是空格字符
    for (; *p != '\0'; p++)
    {
        if (!isspace((unsigned char)*p))
        {
            return false;
        }
    }

    //一切都进行得很顺利,所以传递结果
    *num = result;
    return true;
}

//此函数将从用户那里读取一行输入。它将删除换行符,如果存在的话。如果行太长而无法容纳在缓冲区中,那么该函数将自动重新提示用户输入。失败时,该函数将永远不会返回,而是会打印错误消息并调用"exit"。
void get_line_from_user(const char prompt[], char buffer[], int buffer_size)
{
    for (;;) //无限循环,相当于while(1)
    {
        char *p;

        //提示用户输入
        fputs(prompt, stdout);

        //尝试读取一行输入
        if (fgets(buffer, buffer_size, stdin) == NULL)
        {
            printf("读取输入时出错!\n");
            exit(EXIT_FAILURE);
        }

        //尝试找到换行符
        p = strchr(buffer, '\n');

        //确保整行都被读取(即,缓冲区不太小以存储整行)
        if (p == NULL)
        {
            int c;

            //如果下一个字符是换行符,或者我们已经到达文件末尾(例如,如果输入被从文件中导出或者用户在终端中输入文件末尾),则缺少换行符是可以的
            if ((c = getchar()) != '\n' && !feof(stdin))
            {
                if (ferror(stdin))
                {
                    printf("读取输入时出错!\n");
                    exit(EXIT_FAILURE);
                }

                printf("输入过长,无法容纳在缓冲区中!\n");

                //丢弃剩余的行
                do
                {
                    c = getchar();

                    if (ferror(stdin))
                    {
                        printf("读取输入时出错!\n");
                        exit(EXIT_FAILURE);
                    }

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

                //通过重新启动循环,重新提示用户输入
                continue;
            }
        }
        else
        {
            //通过使用null字符覆盖它来删除换行符
            *p = '\0';
        }

        //输入正确,跳出循环
        break;
    }
}

这个程序的行为

英文:

One of the other answers has already listed and explained the errors in your code.

Therefore, in this answer, I will only show you the code for how I would solve the problem:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;
#include &lt;stdbool.h&gt;
//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(
&quot;Please enter the letter of the class or the age of the student: &quot;,
input, sizeof input
);
//determine whether the user entered an integer
if ( convert_string_to_long( input, &amp;num ) )
{
switch( num )
{
case 4:
case 5:
printf( &quot;For the students of the age %ld, the class will be A.&quot;, num );
break;
case 6:
case 7:
case 8:
printf( &quot;For the students of the age %ld, the class will be B.&quot;, num );
break;
case 9:
case 10:
printf( &quot;For the students of the age %ld, the class will be C.&quot;, num );
break;
default:
printf( &quot;Invalid age! It must be between 4 and 10!\n&quot; );
continue;
}
//input was ok, so break out of infinite loop
break;
}
else
{
if ( input[0] == &#39;\0&#39; )
{
//input is empty, so reprompt user for input without
//printing an error message
continue;
}
if ( input[1] != &#39;\0&#39; )
{
//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] != &#39;\0&#39;; i++ )
{
if ( !isspace( (unsigned char)input[i] ) )
{
printf( &quot;Input must be an integer or a single letter!\n&quot; );
//we cannot use &quot;continue&quot; 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 &#39;A&#39;:
printf (&quot;For students in class A, the age range is between 4-5 years.&quot;);
break;
case &#39;B&#39;:
printf (&quot;For students in class B, the age range is between 6-8 years.&quot;);
break;
case &#39;C&#39;:
printf (&quot;For students in class C, the age range is between 9-10 years.&quot;);
break;
default:
printf( &quot;Invalid letter!\n&quot; );
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, &amp;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 != &#39;\0&#39;; 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 &quot;exit&quot; 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( &quot;Error reading from input!\n&quot; );
exit( EXIT_FAILURE );
}
//attempt to find newline character
p = strchr( buffer, &#39;\n&#39; );
//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()) != &#39;\n&#39; &amp;&amp; !feof(stdin) )
{
if ( ferror(stdin) )
{
printf( &quot;Error reading from input!\n&quot; );
exit( EXIT_FAILURE );
}
printf( &quot;Input was too long to fit in buffer!\n&quot; );
//discard remainder of line
do
{
c = getchar();
if ( ferror(stdin) )
{
printf( &quot;Error reading from input!\n&quot; );
exit( EXIT_FAILURE );
}
} while ( c != &#39;\n&#39; &amp;&amp; c != EOF );
//reprompt user for input by restarting loop
continue;
}
}
else
{
//remove newline character by overwriting it with
//null character
*p = &#39;\0&#39;;
}
//input was ok, so break out of loop
break;
}
}

This program has the following behavior:

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.

As you can see, I have designed the program in such a way that it will check whether the input is valid, and if not, it will automatically reprompt the user for new input.

huangapple
  • 本文由 发表于 2023年5月24日 20:02:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76323312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定