本文介绍了char *程序流十字路口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我反复进入我需要采取行动的情况 相应地以char *的形式输入,并且发现两种方式 接近这个,我会指出哪个是最好的指示。 第一种方法非常小,但是有点硬连线并且真的有很多选择。第二个代码需要3倍的代码,但 更具动态性,更容易看出它的作用。 / *方法#1 *请注意,这个通常出现的代码多于 *这是出于某种原因 * / void do(char *输入){ if(strcmp(input," foo")== 0)do_foo(); else if(strcmp(input," bar") == 0)do_bar(); else if(strcmp(input," baz")== 0)do_baz(); else do_wtf(); } / *方法#2 * / 无效(char *输入){ char * commands [] = {" foo"," bar"," baz"}; enum {FOO = 0,BAR,BAZ,MAX}; int cmd = 0; while(cmd< MAX)if(strcmp(commands [cmd ++],input)== 0)break; 开关(cmd){ 案例FOO:do_foo();打破; 案例BAR:do_bar();休息; 案例BAZ:do_baz(); break; 默认值:do_wtf();休息; } } I repeatedly get into the situation where i need to take actionaccordingly to input in form of a char*, and have found two manners ofapproaching this, i''d appretiate pointers as to which is the best.The first approach is very small, but is kinda hardwired and gets reallycluttery with many options. The second one takes 3 times as much code, butis more dynamic and easy to see what it does./* Approach #1* Note that this one generally comes out with more code than* this out of some reason*/void do(char* input) {if(strcmp(input, "foo") == 0) do_foo();else if(strcmp(input, "bar") == 0) do_bar();else if(strcmp(input, "baz") == 0) do_baz();else do_wtf();} /* Approach #2 */void do(char* input) {char* commands[] = {"foo", "bar", "baz"};enum { FOO = 0, BAR, BAZ, MAX }; int cmd = 0;while(cmd < MAX) if(strcmp(commands[cmd++], input)==0) break; switch(cmd) {case FOO: do_foo(); break;case BAR: do_bar(); break;case BAZ: do_baz(); break;default: do_wtf(); break;}}推荐答案 ro ** @ eudial.mine.nu 写道:我反复进入我需要的情况采取行动因此以char *的形式输入,并且已经找到两种接近这个的方式,我会指出哪个是最好的。第一种方法是非常小,但是有点硬连线,并且有很多选择的杂乱无章。第二个代码需要3倍的代码,但更动态,更容易看到它的作用。 / *方法#1 *请注意,这个通常来了出于某种原因,代码多于 *这个* / void do(char * input){ if(strcmp(input," foo")== 0)do_foo(); else if(strcmp(input," bar")== 0)do_bar(); else if(strcmp(input," baz")== 0) do_baz(); 其他do_wtf(); } / *方法#2 * / void do(char * input){ char * commands [] = {" foo"," bar"," baz"}; enum {FOO = 0,BAR,BAZ,MAX}; int cmd = 0; while(cmd< MAX)if(strcmp(commands [cmd ++],input)== 0)break; switch(cmd){ case FOO: do_foo();破坏; 案例BAR:do_bar();打破; 案例BAZ:do_baz(); break; 默认值:do_wtf();打破; } } I repeatedly get into the situation where i need to take action accordingly to input in form of a char*, and have found two manners of approaching this, i''d appretiate pointers as to which is the best. The first approach is very small, but is kinda hardwired and gets really cluttery with many options. The second one takes 3 times as much code, but is more dynamic and easy to see what it does. /* Approach #1 * Note that this one generally comes out with more code than * this out of some reason */ void do(char* input) { if(strcmp(input, "foo") == 0) do_foo(); else if(strcmp(input, "bar") == 0) do_bar(); else if(strcmp(input, "baz") == 0) do_baz(); else do_wtf(); } /* Approach #2 */ void do(char* input) { char* commands[] = {"foo", "bar", "baz"}; enum { FOO = 0, BAR, BAZ, MAX }; int cmd = 0; while(cmd < MAX) if(strcmp(commands[cmd++], input)==0) break; switch(cmd) { case FOO: do_foo(); break; case BAR: do_bar(); break; case BAZ: do_baz(); break; default: do_wtf(); break; } } 任何一种方法都是可以接受的。 从风格的角度看待它,我倾向于选择 方法2.这与你所描述的原因相同。 但是,请注意,do是一个关键字。您需要更改 函数名称。另外,由于未修改char指针 参数的存储,你应该使用''const char * input''。 示例: #include< stdio.h> #include< string.h> void do_foo(void); void do_bar(void); void do_baz(void); void do_wtf(void); void doit( const char * input); int main(void) { doit(" foo"); 返回0; } 无效do_foo(无效) { puts(Fooooooooooooooo); 返回; } void do_bar(void) { puts(" Barrrrrrrr); 返回; } void do_baz(无效) { puts(Bazzzzzzzzzzzz); 返回; } void do_wtf(无效) { puts(没有给出命令); 返回; } void doit(const char * input) { char * commands [] = {" foo"," bar"," baz"}; enum CMD {FIRST = 0,FOO = 0,ONE = 1,BAR = 1,BAZ,LAST}; enum CMD cmd; for(cmd = FIRST; cmd!=最后; cmd + = ONE) if(strcmp(commands [cmd],input)== 0)break; switch(cmd) { 案例FOO:do_foo();打破; 案例BAR:do_bar();休息; 案例BAZ:do_baz(); break; 默认值:do_wtf();休息; } } - Al Bowers Tampa, Fl USA mailto: xa******@myrapidsys.com (删除x发送电子邮件) http://www.geocities.com/abowers822/ Either approach would be acceptable.Looking at it from a style prespective, I tend to preferapproach 2. It''s for the same reasons as you described. However, note that do is a keyword. You will need to changethe function name. Also, since the storage to the char pointerargument is not modified you should use ''const char *input''. Example:#include <stdio.h>#include <string.h> void do_foo(void);void do_bar(void);void do_baz(void);void do_wtf(void);void doit(const char* input); int main(void){doit("foo");return 0;} void do_foo(void){puts("Fooooooooooooooo");return;} void do_bar(void){puts("Barrrrrrrr");return;} void do_baz(void){puts("Bazzzzzzzzzzzz");return;} void do_wtf(void){puts("No command given");return;} void doit(const char* input){char* commands[] = {"foo", "bar", "baz"};enum CMD {FIRST = 0, FOO = 0,ONE = 1, BAR = 1, BAZ,LAST } ;enum CMD cmd; for(cmd = FIRST; cmd != LAST; cmd+=ONE)if(strcmp(commands[cmd], input)==0) break; switch(cmd){case FOO: do_foo(); break;case BAR: do_bar(); break;case BAZ: do_baz(); break;default: do_wtf(); break;}}--Al BowersTampa, Fl USAmailto: xa******@myrapidsys.com (remove the x to send email) http://www.geocities.com/abowers822/ ro**@eudial.mine.nu 写道: [snip] / *方法#2 * / void do(char *输入){ char * commands [] = {" foo"," bar"," baz"}; enum {FOO = 0,BAR,BAZ,MAX}; int cmd = 0; while(cmd< MAX)if(strcmp(commands [cmd ++],input)== 0)break; switch(cmd){ 案例FOO:do_foo();破坏; 案例BAR:do_bar();打破; 案例BAZ:do_baz(); break; 默认值:do_wtf();打破; } } [ snip ] /* Approach #2 */ void do(char* input) { char* commands[] = {"foo", "bar", "baz"}; enum { FOO = 0, BAR, BAZ, MAX }; int cmd = 0; while(cmd < MAX) if(strcmp(commands[cmd++], input)==0) break; switch(cmd) { case FOO: do_foo(); break; case BAR: do_bar(); break; case BAZ: do_baz(); break; default: do_wtf(); break; } } 这种方法似乎最容易维持两个人的b $ b。一些建议 - 如果命令数量不是太多, 我将它们排在列表中,并使用 a小于或等于比较。 或 如果某些命令使用频率较高 超过其他命令,然后在'命令''数组的开头把它们放在 。 我也会使用`(sizeof(commands)/ sizeof(commands [0]))'' 而不是'MAX'',并使枚举变为类型 - enum {FOO = 0,BAR,BAZ,} cmd; 这种方式(例如gcc)会在新项目时发出警告添加了 到`命令''和枚举类型,但是没有将 添加到switch语句中。不过有点小问题。 --- 如果你感觉很疯狂,你可以结婚 命令字符串和它的函数指针处理程序 到一个结构中,并构建一个数组。 现在你可以消除enum(因为它只是 无论如何都充当了函数指针索引,并且 a可能是很长的switch语句。这个, 当然,假设所有的处理程序都可以使用相同或兼容的原型(你的例子就是这样)。 HTH, Stephen This approach seems the easiest to maintainof the two. A couple of suggestions - If the number of commands isn''t too many,I put them in the list sorted, and usea less than or equal to for the comparison. OR If some of the commands are more heavily usedover the other commands, then put themin the beginning of the `commands'' array. I''d also use `(sizeof(commands) / sizeof(commands[0]))''instead of `MAX'', and make the enum a "type" - enum { FOO = 0, BAR, BAZ, } cmd; This way (e.g. gcc) will warn if a new item is addedto the `commands'' and the enum type, but is notadded to the switch statement. Kinda a minor point, though. --- If you''re _really_ feeling crazy, you could marrythe command string and it''s function pointer handlerinto a structure, and build an array of those. Now you can eliminate the enum (since it''s onlyacting as a function pointer index anyway, anda possibly long switch statement. This, ofcourse, assumes all of the handlers can havethe same or compatible prototype (which your example does).HTH, Stephen < ro ** @ eudial.mine.nu>写道: <ro**@eudial.mine.nu> writes: 我反复进入这种情况我需要采取行动相应地以char *的形式输入,并且已经找到两种接近这个的方式,我会指出哪个是最好的。第一种方法很小,但有点硬连线得到了很多选择的杂乱无章。第二个代码需要3倍的代码,但更动态,更容易看到它的作用。 / *方法#1 *请注意,这个通常来了出于某种原因,代码多于 *这个* / void do(char * input){ if(strcmp(input," foo")== 0)do_foo(); else if(strcmp(input," bar")== 0)do_bar(); else if(strcmp(input," baz")== 0) do_baz(); 其他do_wtf(); } / *方法#2 * / void do(char * input){ char * commands [] = {" foo"," bar"," baz"}; enum {FOO = 0,BAR,BAZ,MAX}; (您可能希望将'MAX'重命名为'NUM'',因为它 表示可能的命令数,而不是最大值命令 数。) int cmd = 0; while(cmd< MAX)if(strcmp(commands [cmd ++],input)== 0 )break; switch(cmd){ case FOO:do_foo();破坏; 案例BAR:do_bar();打破; 案例BAZ:do_baz(); break; 默认值:do_wtf();断开; } } I repeatedly get into the situation where i need to take action accordingly to input in form of a char*, and have found two manners of approaching this, i''d appretiate pointers as to which is the best. The first approach is very small, but is kinda hardwired and gets really cluttery with many options. The second one takes 3 times as much code, but is more dynamic and easy to see what it does. /* Approach #1 * Note that this one generally comes out with more code than * this out of some reason */ void do(char* input) { if(strcmp(input, "foo") == 0) do_foo(); else if(strcmp(input, "bar") == 0) do_bar(); else if(strcmp(input, "baz") == 0) do_baz(); else do_wtf(); } /* Approach #2 */ void do(char* input) { char* commands[] = {"foo", "bar", "baz"}; enum { FOO = 0, BAR, BAZ, MAX };(You might want to rename `MAX'' to something like `NUM'', as itrepresents the number of possible commands, not the maximum commandnumber.) int cmd = 0; while(cmd < MAX) if(strcmp(commands[cmd++], input)==0) break; switch(cmd) { case FOO: do_foo(); break; case BAR: do_bar(); break; case BAZ: do_baz(); break; default: do_wtf(); break; } } 两种方法的缺点是它们可能比较 输入字符串和/每个/命令字符串。这可能会变得很慢 除非你真的只有很少(三个,比如说)命令。 如果你没有太多命令,你可以在第一个字符上使用'switch''语句 ,这已经可以显着减少 必要的字符串比较次数: void do(const char * const input) { 开关(*输入) { case''b'': if(strcmp(input + 1," ar")== 0) do_bar(); else if(strcmp(input + 1," az")== 0) do_baz(); else do_wtf(); 休息; case''f'': if(strcmp(输入+ 1, " oo")== 0) do_foo(); else do_wtf(); 休息; 默认: do_wtf(); 休息; } } 否则,您最好的选择可能就是哈希函数。如果命令 字符串是固定的(即它们的数量和内容都不会在运行时改变),你可以使用完美哈希函数,永远不需要 多于/一/字符串比较。 (谷歌如果你这个词需要更多信息。) 马丁 - , - 。 Martin Dickopp,德国德累斯顿,=, - _-。 =。 /, - ) http://www.zero -based.org/ ((_ /)oo(\_)) \` - ''` - ''(。)` - '' ` - 。 Debian,GNU操作系统的一种变体。 \_ / Both approaches have the disadvantage that they possibly compare theinput string with /every/ command string. That can get quite slowunless you really only have very few (three, say) commands. If you don''t have too many commands, you could use a `switch'' statementon the first character, which can already significantly reduce thenumber of necessary string comparisons: void do (const char *const input){switch (*input){case ''b'':if (strcmp (input + 1, "ar") == 0)do_bar ();else if (strcmp (input + 1, "az") == 0)do_baz ();elsedo_wtf ();break; case ''f'':if (strcmp (input + 1, "oo") == 0)do_foo ();elsedo_wtf ();break; default:do_wtf ();break;}} Otherwise, your best choice is probably a hash function. If the commandstrings are fixed (i.e. their number and content both don''t change atruntime), you could use a "perfect hash function", which never needsmore than at most /one/ string comparison. (Google for the term if youneed more information.) Martin--,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =./ ,- ) http://www.zero-based.org/ ((_/)o o(\_))\ `-'' `-''(. .)`-''`-. Debian, a variant of the GNU operating system. \_/ 这篇关于char *程序流十字路口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-27 05:50