5
#include<stdio.h>

int main(){

    char name[20];

    printf("enter a name ");
    scanf("%s",name);
    switch(name[20]){
        case "kevin" : 
        printf("hello");
        break;
    }
    printf("%s",name);
    getch();
}

似乎它不会起作用。这可能吗?我的意思是有什么方法可以对字符串进行 switch 语句。究竟如何解决问题?

4

8 回答 8

8

C 中的 Switch 语句不像其他语言(例如 Java 7 或 Go)中的那样聪明,您无法打开字符串(也不能将字符串与 比较==)。Switch 只能对整数类型(int、、char等)进行操作。

在您的代码中,您使用以下命令调用 switch:switch(name[20])。这意味着switch(*(name + 20))。换句话说,21号开关char在名称上(因为name[0]是第一个)。由于name只有 20 个字符,您正在访问名称后的任何内存。(这可能会做不可预测的事情)

该字符串"kevin"也被编译为包含该字符串的char[N](where Nis )。strlen("kevin") + 1当你这样做case "kevin"。只有当 name 位于存储字符串的完全相同的内存中时,它才会起作用。所以即使我复制kevin成名字。它仍然不匹配,因为它存储在不同的内存中。

要做你似乎正在尝试的事情,你会这样做:

#include <string.h>
...
    if (strcmp(name, "kevin") == 0) {
        ...
    }

字符串比较(strcmp)根据字符串的不同返回不同的值。例如:

int ord = strcmp(str1, str2);
if (ord < 0)  
    printf("str1 is before str2 alphabetically\n");
else if (ord == 0) 
    printf("str1 is the same as str2\n");
else if (ord > 0)  
    printf("str1 is after str2 alphabetically\n");

旁注:不要scanf("%s", name)以那种形式使用。它会产生一个常见的安全问题fgets,如下所示:(也有一种安全的使用方式scanf

#define MAX_LEN 20
int main() { 
    char name[MAX_LEN]; 
    fgets(name, MAX_LEN, stdin);
    ...
于 2013-08-01T04:01:44.253 回答
6

Switch 语句适用于int值(或enum),但不适用于char数组。

你可以做

if (strcmp(name, "kevin")==0) {
    printf("hello");
}
else if (strcmp(name, "Laura")==0) {
    printf("Allo");
}
else if (strcmp(name, "Mike")==0) {
    printf("Good day");
}
else  {
    printf("Help!");
}
于 2013-08-01T03:28:19.173 回答
2

有很多方法可以解决这个问题!例如,使用一个...

3 字母哈希

#include <stdio.h>

int main(){

    char name[20];

    printf("enter a name ");
    scanf("%s",name);
    switch((int)*name * (int)*(name+1) * (int)*(name+2)){
          case (1275226) : // "kevin"
            printf("hello %s.\n", name);
            break;
          case (1293980) : // "astro"
            printf("welcome %s.\n", name);
            break;
    }
    printf("%d",(int)*name * (int)*(name+1) * (int)*(name+2));
}
于 2013-08-01T03:52:15.873 回答
0

不,您不能将switchC 中的语句与字符串或字符数组的值一起使用。最接近的替代方法是使用某种数据结构将字符串映射到函数指针。可以在使用字符串查找后调用函数指针。

于 2013-08-01T03:14:03.537 回答
0

switch使用语句时记住规则。

切换约束

1. switch 语句的控制表达式必须是“整数类型”。

2、每个case标签的表达式必须是整数常量表达式,同一switch语句中的两个case常量表达式转换后的值不能相同。switch 语句中最多可以有一个默认标签。

3.任何封闭的 switch 语句可能有一个默认标签或 case 常量表达式,其值与封闭 switch 语句中的 case 常量表达式重复。

于 2013-08-01T03:59:02.367 回答
0

由于名称被声明为 char 类型,因此在方法内部使用"%c"而不是使用会更好。"%s"scanf()

于 2014-03-10T04:38:03.773 回答
0

您可以使用将字符串转换为哈希码整数的“hash-string.h”库。创建一个头文件并粘贴此代码: http ://www.opensource.apple.com/source/gcc/gcc-5484/intl/hash-string.h

#include <stdio.h>
#include <stdlib.h>
#include "hash-string.h"

int main(){

  char name[20];

  printf("Enter a name: ");
  scanf("%s",name);

  unsigned long nameInt = hash_string(name);

  switch(nameInt){
    case 7458046 /* "kevin" */: { printf("Hello %s", name); break; }
    default: { printf("You are not kevin"); }
  }

  printf("\n");
  return 0;
}
于 2014-05-18T14:46:49.947 回答
0

如果您在对特定字符串执行特定操作之后,这意味着您提前知道这些字符串。这反过来意味着它们的数量是有限的,是可数的,例如一组 N 个命令:

const char * commands[] = {
 "command-1",
 "command-2",
 ...
 "command-N"

}

要使用 swtich 从您的代码中处理上述数组中的这些命令,您需要知道它们的索引,这很容易出错。所以给他们编号,给他们一个ID:

enum Command_id {
  NO_COMMAND,
  COMMAND_1,
  COMMAND_2,
  //...
  COMMAND_N,
};

现在使用结构将上述两者放在一起:

struct Command_info {
  const char * command;
  enum Command_id id;
} command_infos[] = {
  {"", NO_COMMAND},
  {"command-1", COMMAND_1},
  {"command-2", COMMAND_2},
  // ...
  {"command-N", COMMAND_N},
};

现在您有了很好的字符串及其相关 ID 的映射。为了能够在运行时从字符串映射到 ID,需要搜索上面的映射。要以有效的方式执行此操作,您需要使用二进制搜索。C 库证明bsearch()了这一点。唯一的前提是要搜索的数组需要排序。

排序使用qsort()也由 C 库证明。为了qsort()工作,我们需要一个比较函数:

int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
  const struct Command_info * pCI1 = pvCI1;
  const struct Command_info * pCI2 = pvCI2;

  return strcmp(pCI1->command, pCI2->command);
}

qsort()像这样打电话

qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);

现在,由于数组已排序,因此可以使用bsearch(). 对于“COMMAND-2”,它看起来像这样:

    ... = bsearch(&(struct Command_info){"COMMAND-2", NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);

将所有这些放在一起可能会导致:

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


enum Command_id {
  NO_COMMAND,
  COMMAND_1,
  COMMAND_2,
  //...
  COMMAND_N,
};

struct Command_info {
  const char * command;
  enum Command_id id;
} command_infos[] = {
  {"", NO_COMMAND},
  {"command-1", COMMAND_1},
  {"command-2", COMMAND_2},
  // ...
  {"command-N", COMMAND_N},
};


int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
  const struct Command_info * pCI1 = pvCI1;
  const struct Command_info * pCI2 = pvCI2;

  return strcmp(pCI1->command, pCI2->command);
}


int main(int argc, char ** argv)
{
  qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);


  {
    enum Command_id command_id = NO_COMMAND;
    struct Command_info * pCI = bsearch(&(struct Command_info){argv[1], NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);

    if (NULL == pCI)
    {
      printf("Command = '%s' is unknown\n", argv[1]);
    }
    else
    {
      printf("Command = '%s' --> ID = %d\n", pCI->command, pCI->id);


      switch(command_id)
      {
        case COMMAND_1:
          /* perform action on COMMAND 1 here */
          break;

        case COMMAND_2:
          /* perform action on COMMAND 1 here */
          break;

        default:
          /* unknow command, do nothing */
          break;
      }
    }
  }
}

像这样称呼它:

./a.out command-1

给予:

Command = 'command-1' --> ID = 1

或者:

./a.out command-bla

给予:

Command = 'command-bla' is unknown

甚至

./a.out ""

给予:

Command = '' --> ID = 0
于 2018-04-01T09:25:22.757 回答