【问题标题】:Switch case messes up my array that im trying to convertSwitch case 弄乱了我试图转换的数组
【发布时间】:2019-10-26 15:10:58
【问题描述】:

我是 C 的新手,我试图将字母转换为键(就像在旧的移动键盘上一样),但开关盒总是以某种方式最终弄乱了数组。 当我尝试测试该值时,它返回的字符与数组中的字符完全不同。例如字符编号 32 而不是大写 V。

char *LetterToKey(char name[101])
{
    char number[101];
    bool unknwn = false;

    for(int i = 0; i<101; i++)
            {
                if(unkwn) break;
                switch (name[i])
                {

                case 'A':
                case 'B':
                case 'C':
                case 'a':
                case 'b':
                case 'c': number[i] = '2'; break;

                case 'D':
                //...

                default:
                    printf("%d\n", (int)name[i]);
                    unknwn = true;
                    break;
                }
            }
            return number;
}

【问题讨论】:

  • 请收下tour,学习How to Ask。已经注意了:您正在返回一个指向一个变量的指针,该变量 not 不再存在于函数之外。
  • 当询问有关运行时问题的问题时,就像这个问题一样,请发布minimal reproducible example,以便我们可以复制问题并帮助您调试它
  • 数组:number[] 是函数本地的,所以函数退出时会“消失”。试图返回数组只会返回一个地址,在堆栈上,数组:number[] 所在的位置。在函数退出后尝试访问该数组会导致未定义的行为

标签: c arrays switch-statement


【解决方案1】:

以下建议代码:

  1. 干净编译
  2. 检查错误
  3. 要求调用者将返回的指针传递给free()
  4. 避免使用“幻数”(如 101)
  5. 正确终止生成的字符数组,使其不包含垃圾/未初始化的字符

现在,建议的代码:

#include <ctype.h>   // toupper()
#include <stdlib.h>  // calloc()
#include <stdio.h>   // printf()

#define MAX_BUF_LEN 101


char *LetterToKey( char *name )
{
    char *number = calloc( MAX_BUF_LEN+1, sizeof( char ) );
    if( !number )
    {
        return NULL;
    }

    // implied else, calloc successful

    size_t i = 0;

    while( i < MAX_BUF_LEN && number[ i ] ) 
    {
        switch ( toupper(name[i]))
        {
            case 'A':
            case 'B':
            case 'C':
                number[i] = '2'; 
                break;

            case 'D':
            case 'E':
            case 'F':
                number[i] = '3';
                break;

            // etc

            default:
                printf("unexpected char: %c\n", name[i]);
                number[ i ] = ' ';
                break;
        }
    }

    return number;
}

当然,如果调用者正确地 NUL 终止了输入,那么代码可以简化为:

#include <ctype.h>   // toupper()
#include <stdlib.h>  // calloc()
#include <stdio.h>   // printf()
#include <string.h>  // strlen()


char *LetterToKey( char *name )
{
    char *number = calloc( strlen( name )+1, sizeof( char ) );
    if( !number )
    {
        return NULL;
    }

    // implied else, calloc successful

    for( size_t i=0; number[ i ]; i++ ) 
    {
        switch ( toupper(name[i]))
        {
            case 'A':
            case 'B':
            case 'C':
                number[i] = '2'; 
                break;

            case 'D':
            case 'E':
            case 'F':
                number[i] = '3';
                break;

            // etc

            default:
                printf("unexpected char: %c\n", name[i]);
                number[ i ] = ' ';
                break;
        }
    }

    return number;
}

【讨论】:

  • // etc - 整个开关可以优化为number[i] = (toupper(name[i]) - 'A') / 3 + '2';
  • @KamilCuk,虽然这是真的,但我不想(非常)扰乱 OP 给出的逻辑
猜你喜欢
  • 2020-01-15
  • 1970-01-01
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
相关资源
最近更新 更多