2017-12-28 41 views
2
int a = 0 , b = 0; 
char* c = NULL; 

int main(int argc , char ** argv){ 

    c = argv[2]; 
    a = atoi(argv[1]); 
    b = atoi(argv[3]); 

    switch(c){ 

     case "+": printf(a+b); 
        break; 
    } 

    printf("\n\n"); 

    return 0; 
} 
+1

番号:

の例では、次のようになります。それらをintに変換し、それらをASCIIコードに基づいて切り替えます。 – qwn

答えて

1

いや、それができないのです。

switch文の制御式が整数型でなければならないC11、章§6.8.4.2

を引用。あなたのケースで

1

、あなたは整数型を持つリテラル文字を(使用することが可能です、その場合には、switch文で渡された文字列の文字列ではなく、最初の(そして唯一の文字)を必要としていないようです)case文で:

if (strlen(c)==1) 
{ 
    switch(c[0]){ 

    case '+': printf(a+b); 
       break; 
    ... 
    } 
} 

文字列に複数の文字を持っていたときに、いくつかの良い他の選択肢がbest way to switch on a string in Cに記述されています。

+1

私はこれを知っていると確信していますが、Cでは '+'は 'int'型です。 – Bathsheba

+0

"Cでは、文字リテラルはint型として扱われますが、C++と同じように、文字リテラルはchar型として扱われますが、その違いを認識していませんでした。知っておいてよかった。誰がC++がCのサブセットであると言ったのですか? –

3

ありませんあなたがすることはできません。 switchのケースラベルは、積分型の時間評価可能な定数式をコンパイルする必要があります。 '+'よう

しかしintリテラルは、その要件を満たします。

(そのことについてはenum値がそう。通り)いくつかの民族は、彼らはそれが可読性に役立ちますが、その時点で、あなたはあきらめていると主張としてcaseラベルとして実装定義の複数文字リテラル(例えば'eax')を使用したいです異なるプラットフォーム間での一貫した動作

NULで終了するcharアレイの値を分岐する必要がある場合は、ifブロックを使用してください。

1

答えには2つのケースがあります。..

まず6.8.4.2switch場合)

switch文の制御式は、第二6.8.4.2整数 タイプ

を持たなければなりませんcaseステートメント)

各caseラベルの式は同じ switch文で整数定数 表現とケース定数式の無い2でなければなら

かいつまんで変換した後に同じ値を持たなければなりませんそのような文字列リテラルは使用できません。スイッチ制御式でもcaseではありません。

strcmpを使用して文字列比較を実行してから、if-else調整を実行できます。あなたがこれを頼む側のコンテキストでは、あなたは、単に全体ではなく、リテラルを渡すの文字+argv[2][0])を渡すことができます。そうすれば、charswitchの式に渡して、それに従って処理します。

2

いいえ、できません。スイッチは、数値型と拡張子型とを比較するためのものです。 は、代わりにあなたがのstrcmp機能を使用する必要があり、文字列ヘッダに含ま:

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

int main(int argc, char * argv[]) { 
    if (argc != 4) { 
    puts("Incorrect usage"); 
    return 1; 
    } 
    /* You should check the number of arguments */ 

    char * op = argv[1]; 
    int a = atoi(argv[2]); 
    int b = atoi(argv[3]); 
    /* You should check correct input too */ 

    if (strcmp(op, "+") == 0) 
    printf("%d + %d = %d\n", a, b, a + b); 
    else if (strcmp(op, "-") == 0) 
    printf("%d - %d = %d\n", a, b, a - b); 
    /* Add more functions here */ 

    return 0; 
} 
+0

はい!私はこれを試して、働いた!しかし、これはこのようなことを行うための方法ですか? – Rucha

+0

@ RuchiM.Mewada:他にもあるが、彼らは言語との不必要な戦いをしている。これはこれまでのところ最良の方法です:私は '!strcmp'を' strcmp == 0'にすることを好みます。しかし、まだupvoteを取得します。 – Bathsheba

+0

スイッチのパフォーマンスと比較しても、ここで問題になる可能性があります。少なくとも、各値に対して等しいことを実行していません。 – alk

0

ありません。しかし、はい、できます。

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

// The way you store and search for names is entirely 
// up to you. This is a simple linear search of an 
// array. If you have a lot of names, you might choose 
// a better storage + lookup, such as a hash table. 
int find(const char** ss, int n, const char* s) 
{ 
    int i = 0; 
    while (i < n) 
    if (strcmp(ss[i], s) == 0) break; 
    else       i += 1; 
    return i; 
} 

// A bevvy of little utilities to help out. 
char* strupper(char* s) 
{ 
    char* p = s; 
    while ((*p = toupper(*p))) ++p; 
    return s; 
} 

char* zero(char* p) { if (p) *p = 0; return p; } 

#define STRINGIFY(S) STRINGIFY0(S) 
#define STRINGIFY0(S) #S 

int main() 
{ 
    // Our list of names are enumerated constants with associated 
    // string data. We use the Enum Macro Trick for succinct ODR happiness. 
    #define NAMES(F) \ 
    F(MARINETTE) \ 
    F(ADRIAN) \ 
    F(ALYA) \ 
    F(DINO) 
    #define ENUM_F(NAME) NAME, 
    #define STRING_F(NAME) STRINGIFY(NAME), 
    enum names { NAMES(ENUM_F) NUM_NAMES }; 
    const char* names[ NUM_NAMES ] = { NAMES(STRING_F) NULL }; 
    #undef STRING_F 
    #undef ENUM_F 
    #undef NAMES 

    // Ask user for a name 
    char s[ 500 ]; 
    printf("name? "); 
    fflush(stdout); 
    fgets(s, sizeof(s), stdin); 
    zero(strchr(s, '\n')); 

    // Preprocess and search for the name 
    switch (find(names, sizeof(names)/sizeof(*names), strupper(s))) 
    { 
    case MARINETTE: puts("Ladybug!"); break; 
    case ADRIAN: puts("Chat Noir!"); break; 
    case ALYA:  
    case DINO:  puts("Best friend!"); break; 
    default:  puts("Who?"); 
    } 
} 

が、これは純粋な、純粋な手品で動作し、テキスト値の大規模なコレクションには適していません覚えておいてください。

また、一致の妥当性は、ユーザーの入力を前処理する度合いに完全に依存します。この例では大文字小文字を無視しますが、より高度なアプリケーションではさらに高度なマッチングを行うことがあります。

+0

私はすべてのおかげで!!私はそれを理解し、修正しました!! tq – Rucha

0

他の人がCで指摘したように、スイッチの引数としても文字列も、ケースラベルも使用できません。

この制限を回避するには、各文字列を特定の整数にマップし、これをスイッチに渡すことができます。

マップを検索するには、標準C bsearch()機能を使用してマップを検索する必要があります。

の例では、次のようになります。

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

enum Operation { 
    OP_INVALID = -1, 
    OP_ADD, 
    OP_SUBTRACT, 
    OP_MULTIPLY, 
    OP_DIVIDE, 
    OP_MAX 
}; 

struct Operation_Descriptor { 
    char * name; 
    enum Operation op; 
}; 

struct Operation_Descriptor operations [] = { 
    {"add", OP_ADD}, 
    {"subtract", OP_SUBTRACT}, 
    {"multiply", OP_MULTIPLY}, 
    {"divide", OP_DIVIDE} 
}; 

int cmp(const void * pv1, const void * pv2) 
{ 
    const struct Operation_Descriptor * pop1 = pv1; 
    const struct Operation_Descriptor * pop2 = pv2; 

    return strcmp(pop1->name, pop2->name); 
} 

int main(int argc, char ** argv) 
{ 
    size_t s = sizeof operations/sizeof *operations; 

    /* bsearch() requires the array to search to be sorted. */ 
    qsort(operations, s, sizeof *operations, cmp); 

    { 
    struct Operation_Descriptor * pop = 
     bsearch(
     &(struct Operation_Descriptor){argv[1], OP_INVALID}, 
     operations, s, sizeof *operations, cmp); 

    switch(pop ?pop->op :OP_INVALID) 
    { 
     case OP_ADD: 
     /* Code to add goes here, */ 
     break; 

     case OP_SUBTRACT: 
     /* Code to subtract goes here, */ 
     break; 

     case OP_MULTIPLY: 
     /* Code to multiply goes here, */ 
     break; 

     case OP_DIVIDE: 
     /* Code to divide goes here, */ 
     break; 

     case OP_INVALID: 

     default: 
     fprintf(stderr, "unhandled or invalid operation '%s'\n", argv[1]); 
     break; 
    } 
    } 
} 

場合はPOSIXの1にもマッピングを検索する最速の方法ですハッシュテーブルを、使用することができます。ことはできませんが、あなたが文字で切り替えることができ

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

enum Operation { 
    OP_INVALID = -1, 
    OP_ADD, 
    OP_SUBTRACT, 
    OP_MULTIPLY, 
    OP_DIVIDE, 
    OP_MAX 
}; 

struct Operation_Descriptor { 
    char * name; 
    enum Operation op; 
}; 

struct Operation_Descriptor operations [] = { 
    {"add", OP_ADD}, 
    {"subtract", OP_SUBTRACT}, 
    {"multiply", OP_MULTIPLY}, 
    {"divide", OP_DIVIDE} 
}; 

int main(int argc, char ** argv) 
{ 
    if (0 == hcreate(5)) 
    { 
    perror("hcreate() failed"); 
    exit(EXIT_FAILURE); 
    } 

    for (size_t i = 0; i < s; ++i) 
    { 
    if (!hsearch((ENTRY){operations[i].name, &operations[i].op}, ENTER)) 
    { 
     perror("hsearch(ENTER) failed"); 
     exit(EXIT_FAILURE); 
    } 
    } 

    { 
    ENTRY * ep = hsearch((ENTRY){argv[1], NULL}, FIND); 

    switch(ep ?*((enum Operation *)ep->data) :OP_INVALID) 
    { 
     case OP_ADD: 
     /* Code to add goes here, */ 
     break; 

     case OP_SUBTRACT: 
     /* Code to subtract goes here, */ 
     break; 

     case OP_MULTIPLY: 
     /* Code to multiply goes here, */ 
     break; 

     case OP_DIVIDE: 
     /* Code to divide goes here, */ 
     break; 

     case OP_INVALID: 

     default: 
     fprintf(stderr, "unhandled or invalid operation '%s'\n", argv[1]); 
     break; 
    } 
    } 

    hdestroy(); /* Clean up. */ 
} 
関連する問題