错误:跳转到案例标签
我写了一个涉及使用switch语句的程序…但是编译时显示:
错误:跳转到案例标签。
为什么这样做?
#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; }
问题是,除非使用明确的{ }
块,否则在一个case
中声明的variables在后续case
中仍然可见, 但是由于初始化代码属于另一个case
, 因此它们将不会被初始化 。
在下面的代码中,如果foo
等于1,那么一切正常,但是如果它等于2,我们将意外地使用存在但可能包含垃圾的i
variables。
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
代替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; }
在案件陈述中声明新variables是造成问题的原因。 在{}
所有的case
语句会将新声明的variables的范围限制在解决问题的当前正在执行的case中。
switch(choice) { case 1: { // ....... }break; case 2: { // ....... }break; case 3: { // ....... }break; }
C ++ 11标准跳过一些初始化
JohannesD给出了一个解释,现在的标准。
C ++ 11 N3337标准草案 6.7声明声明3)说:
可以将其转换为块,但不能以绕过具有初始化的声明的方式。 从具有自动存储持续时间的variables不在范围内的点跳转(87)到其在范围内的点的程序是不合格的,除非variables具有标量types,具有简单的默认构造函数的类types和平凡的析构函数,这些types之一的cv限定版本,或者前面types之一的数组,并且声明时没有初始值设定项(8.5)。
87)从switch语句转换为case标签在这方面被认为是一个跳跃。
[例如:
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开始,现在的错误信息是:
穿越初始化
C
C允许: c99转到初始化
C99 N1256标准草案 附件I常见警告2)说:
具有自动存储持续时间的对象的初始化块被跳转到