使用数组上的字符串切换语句

#include 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语句。 实际上如何解决问题?

C语言中的switch语句不像其他语言(例如Java 7或Go)中的那样,不能打开字符串(也不能用==来比较字符串)。 Switch只能对整数类型( intchar等)进行操作。

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

字符串"kevin"被编译为char[N] (其中Nstrlen("kevin") + 1 ),其中包含字符串。 当你做case "kevin" 。 它只有在名称与存储字符串的内存完全相同时才有效。 即使我将kevin复制到名字中也是如此。 它仍然不匹配,因为它存储在不同的内存中。

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

 #include  ... 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() { name[MAX_LEN]; fgets(name, MAX_LEN, stdin); ... 

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!"); } 

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

3个字母的哈希

 #include  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)); } 

不,您不能在C中使用带有字符串或字符数组值的switch语句。 最接近的替代方法是使用某种数据结构映射字符串来实现指针。 在使用字符串查找函数之后,可以调用函数指针。

因为名称被声明为char类型,所以如果在scanf()方法中使用"%c"而不是使用"%s"会更好。

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

 #include  #include  #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; } 

使用switch语句时请记住规则。

切换约束

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

2.每个case标签的表达式应为整数常量表达式,并且同一switch语句中的两个case常量表达式在转换后不应具有相同的值。 switch语句中最多可能有一个默认标签。

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

如果您在对特定字符串执行特定操作后,这意味着您事先知道字符串。 这反过来意味着它们的数量是有限的,是可数的,例如一组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库为此certificate了bsearch() 。 唯一的先决条件是要搜索的数组需要排序。

要排序使用qsort()也是由C库certificate。 要让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  #include  #include  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