ত্রুটি: কেস লেবেলে ঝাঁপুন


229

আমি একটি প্রোগ্রাম লিখেছিলাম যা এতে স্যুইচ স্টেটমেন্টগুলির ব্যবহারের সাথে জড়িত ... তবে সংকলনের উপর এটি দেখায়:

ত্রুটি: কেস লেবেলে ঝাঁপুন।

কেন এটা করে?

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>

using namespace std;

class contact
{
public:
    string name;
    int phonenumber;
    string address;
    contact() {
        name= "Noname";
        phonenumber= 0;
        address= "Noaddress";
    }
};

int main() {
    contact *d;
    d = new contact[200];
    string name,add;
    int choice,modchoice,t;//Variable for switch statement
    int phno,phno1;
    int i=0;
    int initsize=0, i1=0;//i is declared as a static int variable
    bool flag=false,flag_no_blank=false;

    //TAKE DATA FROM FILES.....
    //We create 3 files names, phone numbers, Address and then abstract the data from these files first!
    fstream f1;
    fstream f2;
    fstream f3;
    string file_input_name;
    string file_input_address;
    int file_input_number;

    f1.open("./names");
    while(f1>>file_input_name){
        d[i].name=file_input_name;
        i++;
    }
    initsize=i;

    f2.open("./numbers");
    while(f2>>file_input_number){
        d[i1].phonenumber=file_input_number;
        i1++;
    }
    i1=0;

    f3.open("./address");
    while(f3>>file_input_address){
        d[i1].address=file_input_address;
        i1++;
    }

    cout<<"\tWelcome to the phone Directory\n";//Welcome Message
    do{
        //do-While Loop Starts
        cout<<"Select :\n1.Add New Contact\n2.Update Existing Contact\n3.Display All Contacts\n4.Search for a Contact\n5.Delete a  Contact\n6.Exit PhoneBook\n\n\n";//Display all options
        cin>>choice;//Input Choice from user

        switch(choice){//Switch Loop Starts
        case 1:
            i++;//increment i so that values are now taken from the program and stored as different variables
            i1++;
            do{
                cout<<"\nEnter The Name\n";
                cin>>name;
                if(name==" "){cout<<"Blank Entries are not allowed";
                flag_no_blank=true;
                }
            }while(flag_no_blank==true);
            flag_no_blank=false;
            d[i].name=name;
            cout<<"\nEnter the Phone Number\n";
            cin>>phno;
            d[i1].phonenumber=phno;
            cout<<"\nEnter the address\n";
            cin>>add;
            d[i1].address=add;
            i1++;
            i++;
            break;//Exit Case 1 to the main menu
        case 2:
            cout<<"\nEnter the name\n";//Here it is assumed that no two contacts can have same contact number or address but may have the same name.
            cin>>name;
            int k=0,val;
            cout<<"\n\nSearching.........\n\n";
            for(int j=0;j<=i;j++){
                if(d[j].name==name){
                    k++;
                    cout<<k<<".\t"<<d[j].name<<"\t"<<d[j].phonenumber<<"\t"<<d[j].address<<"\n\n";
                    val=j;
                }
            }
            char ch;
            cout<<"\nTotal of "<<k<<" Entries were found....Do you wish to edit?\n";
            string staticname;
            staticname=d[val].name;
            cin>>ch;
            if(ch=='y'|| ch=='Y'){
                cout<<"Which entry do you wish to modify ?(enter the old telephone number)\n";
                cin>>phno;
                for(int j=0;j<=i;j++){
                    if(d[j].phonenumber==phno && staticname==d[j].name){
                        cout<<"Do you wish to change the name?\n";
                        cin>>ch;
                        if(ch=='y'||ch=='Y'){
                            cout<<"Enter new name\n";
                            cin>>name;
                            d[j].name=name;
                        }
                        cout<<"Do you wish to change the number?\n";
                        cin>>ch;
                        if(ch=='y'||ch=='Y'){
                            cout<<"Enter the new number\n";
                            cin>>phno1;
                            d[j].phonenumber=phno1;
                        }
                        cout<<"Do you wish to change the address?\n";
                        cin>>ch;
                        if(ch=='y'||ch=='Y'){
                            cout<<"Enter the new address\n";
                            cin>>add;
                            d[j].address=add;
                        }
                    }
                }
            }
            break;
        case 3 : {
            cout<<"\n\tContents of PhoneBook:\n\n\tNames\tPhone-Numbers\tAddresses";
            for(int t=0;t<=i;t++){
                cout<<t+1<<".\t"<<d[t].name<<"\t"<<d[t].phonenumber<<"\t"<<d[t].address;
            }
            break;
                 }
        }
    }
    while(flag==false);
    return 0;
}

1
আপনি কোন কোডটি সংকলনের চেষ্টা করছেন? আপনি কোন সংকলক ব্যবহার করছেন? আপনি কি বন্ধনী প্রতিটি caseব্লক বন্ধ আছে?
কোডি গ্রে

2
এটি চিত্তাকর্ষকভাবে চতুর্দিকে ত্রুটির বার্তাটি
জোকসাইক্যাক

উত্তর:


437

সমস্যাটি হ'ল যে একটিতে ঘোষিত ভেরিয়েবলগুলি caseপরবর্তী caseস্পষ্টগুলিতে এখনও স্পষ্ট হয় যদি না কোনও স্পষ্ট { }ব্লক ব্যবহার করা হয় তবে সেগুলি আরম্ভ করা হবে না কারণ সূচনা কোড অন্যটির সাথে সম্পর্কিত case

নিম্নলিখিত কোডে, foo1 এর সমান হলে , সবকিছু ঠিক আছে, তবে এটি 2 এর সমান হলে আমরা ঘটনাক্রমে iভেরিয়েবলটি ব্যবহার করব যা উপস্থিত রয়েছে তবে সম্ভবত আবর্জনা রয়েছে।

switch(foo) {
  case 1:
    int i = 42; // i exists all the way to the end of the switch
    dostuff(i);
    break;
  case 2:
    dostuff(i*2); // i is *also* in scope here, but is not initialized!
}

একটি সুস্পষ্ট ব্লকে কেস মোড়ানো সমস্যা সমাধান করে:

switch(foo) {
  case 1:
    {
        int i = 42; // i only exists within the { }
        dostuff(i);
        break;
    }
  case 2:
    dostuff(123); // Now you cannot use i accidentally
}

সম্পাদন করা

আরও সম্প্রসারিত করার জন্য, switchবিবৃতি একটি মাত্র বিশেষ করে অভিনব ধরনের goto। এখানে কোডটির একটি অ্যালবামস টুকরা একই সমস্যাটি প্রদর্শন করছে তবে এর gotoপরিবর্তে একটি ব্যবহার করছে switch:

int main() {
    if(rand() % 2) // Toss a coin
        goto end;

    int i = 42;

  end:
    // We either skipped the declaration of i or not,
    // but either way the variable i exists here, because
    // variable scopes are resolved at compile time.
    // Whether the *initialization* code was run, though,
    // depends on whether rand returned 0 or 1.
    std::cout << i;
}

1
অন্যান্য ব্যাখ্যার জন্য এই স্থির এলএলভিএম বাগ রিপোর্টটি দেখুন: llvm.org/bugs/show_bug.cgi?id=7789
ফ্রান্সেস্কো

70

ক্ষেত্রে বিবৃতিতে নতুন ভেরিয়েবলের ঘোষণা হ'ল যা সমস্যা সৃষ্টি করে। সমস্ত caseবিবৃতি এলেকৃত করা {}সদ্য ঘোষিত ভেরিয়েবলের সুযোগটি বর্তমানে কার্যকরকারী ক্ষেত্রে সীমাবদ্ধ করবে যা সমস্যার সমাধান করে।

switch(choice)
{
    case 1: {
       // .......
    }break;
    case 2: {
       // .......
    }break;
    case 3: {
       // .......
    }break;
}    

ক্লিনার ফিক্স নির্দেশ
yc_yuy

যদি আমি কোঁকড়া ধনুর্বন্ধনীগুলির মধ্যে ব্রেক স্টেটমেন্ট রাখি তবে কোনও সমস্যা হবে?
বিশাল শর্মা

10

কিছু প্রাথমিককরণের উপর ঝাঁপিয়ে পড়তে সি ++ 11 মানক

জোহনেস ডি একটি ব্যাখ্যা দিয়েছেন, এখন মানদণ্ডগুলির জন্য।

সি ++ 11 N3337 মান খসড়া 6.7 "ঘোষণা বিবৃতি" বলেছেন:

3 কোনও ব্লকে স্থানান্তর করা সম্ভব, তবে এমনভাবে নয় যে প্রারম্ভিককরণের সাথে ঘোষণাকে বাইপাস করে। এমন একটি প্রোগ্রাম যা ())) এমন একটি বিন্দু থেকে লাফ দেয় যেখানে স্বয়ংক্রিয় স্টোরেজ সময়কালের সাথে একটি ভেরিয়েবল এমন বিন্দুতে অবধি থাকে না যেখানে এটি স্কোপে থাকে না যদি ভেরিয়েবলের স্কেলার টাইপ না হয়, তুচ্ছ ডিফল্ট কনস্ট্রাক্টর সহ শ্রেণীর ধরণ এবং তুচ্ছ ডেস্ট্রাক্টর, এই ধরণের যে কোনও একটি সিভি-যোগ্য সংস্করণ, বা পূর্ববর্তী ধরণেরগুলির একটি অ্যারে এবং প্রারম্ভিক (8.5) ছাড়াই ঘোষণা করা হয় declared

87) কেস লেবেলে একটি স্যুইচ স্টেটমেন্টের শর্ত থেকে স্থানান্তরকে এই ক্ষেত্রে এক লাফ হিসাবে বিবেচনা করা হয়।

[উদাহরণ:

void f() {
   // ...
  goto lx;    // ill-formed: jump into scope of a
  // ...
ly:
  X a = 1;
  // ...
lx:
  goto ly;    // OK, jump implies destructor
              // call for a followed by construction
              // again immediately following label ly
}

- শেষ উদাহরণ]

GCC 5.2 হিসাবে, ত্রুটি বার্তাটি এখন বলে:

এর সূচনা অতিক্রম করে

সি

সি এটির অনুমতি দেয়: সি 99 অতীত সূচনা

C99 N1256 মান খসড়া অ্যানেক্স আমি "কমন সতর্কবার্তা" বলেছেন:

2 স্বয়ংক্রিয় স্টোরেজ সময়কাল একটি অবজেক্টের সূচনা সহ একটি ব্লকটি লাফানো হয়


6

জোহানেসডির উত্তরটি সঠিক, তবে আমি মনে করি সমস্যার কোনও দিকটি এটি সম্পূর্ণ পরিষ্কার নয়।

উদাহরণস্বরূপ তিনি দেয় ঘোষণা এবং পরিবর্তনশীল সূচনা iক্ষেত্রে 1, এবং তারপর 2. ক্ষেত্রে এটি ব্যবহার করার জন্য তাঁর যুক্তি যে যদি সুইচ কেস 2 সোজা গিয়ে হয় চেষ্টা করে iসক্রিয়া হচ্ছে না ব্যবহার করা হবে এবং কেন সেখানে একটি সংকলন এই দেশ ত্রুটি. এই মুহুর্তে, কেউ ভাবতে পারে যে কোনও ক্ষেত্রে ঘোষিত ভেরিয়েবলগুলি অন্য ক্ষেত্রে কখনও ব্যবহার না করা হলে কোনও সমস্যা হবে না। উদাহরণ স্বরূপ:

switch(choice) {
    case 1:
        int i = 10; // i is never used outside of this case
        printf("i = %d\n", i);
        break;
    case 2:
        int j = 20; // j is never used outside of this case
        printf("j = %d\n", j);
        break;
}

এক এই প্রোগ্রাম কম্পাইল করার আশা করতে পারে, উভয় থেকে iএবং jশুধুমাত্র ক্ষেত্রে তাদের ডিক্লেয়ার ভিতরে ব্যবহার করা হয়। দুর্ভাগ্যক্রমে, সি ++ এ এটি সংকলন করে না: যেমন সিরো সান্তিলি 法轮功 露 宪 六四 事件 法轮功 法轮功 ব্যাখ্যা করেছেন , আমরা কেবল লাফিয়ে case 2:উঠতে পারি না , কারণ এটি প্রারম্ভিককরণের সাথে ঘোষণাটি এড়িয়ে যাবে i, এবং যদিও case 2এটি মোটেও ব্যবহার করে না i, এটি এখনও সি ++ এ নিষিদ্ধ।

মজার ব্যাপার হচ্ছে, কিছু মানিয়ে (একটি সঙ্গে #ifdefথেকে #includeউপযুক্ত হেডার ও লেবেলগুলির পর একটি সেমিকোলন, কারণ লেবেল শুধুমাত্র বিবৃতি দ্বারা অনুসরণ করা যেতে পারে এবং ঘোষণা সি বিবৃতিগুলির মতো গণনা করা হয় না ), এই প্রোগ্রাম আছে কম্পাইল সি হিসাবে:

// Disable warning issued by MSVC about scanf being deprecated
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif

int main() {

    int choice;
    printf("Please enter 1 or 2: ");
    scanf("%d", &choice);

    switch(choice) {
        case 1:
            ;
            int i = 10; // i is never used outside of this case
            printf("i = %d\n", i);
            break;
        case 2:
            ;
            int j = 20; // j is never used outside of this case
            printf("j = %d\n", j);
            break;
    }
}

Http://rextester.com এর মতো একটি অনলাইন সংকলককে ধন্যবাদ আপনি এমএসভিসি, জিসিসি বা ক্ল্যাং ব্যবহার করে দ্রুত এটি সি বা সি ++ হিসাবে সংকলনের চেষ্টা করতে পারেন। সি হিসাবে এটি সর্বদা কাজ করে (কেবল এসটিডিন সেট করা মনে রাখবেন!), কারণ সি ++ কোনও সংকলক এটি গ্রহণ করে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.