Napisałem program, który wymaga użycia instrukcji switch ... Jednak na kompilacji pokazuje:
Błąd: Przejdź do etykiety sprawy.
Dlaczego to robi?
#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
blok w nawiasach klamrowych?Odpowiedzi:
Problem polega na tym, że zmienne zadeklarowane w jednym
case
są nadal widoczne w kolejnychcase
s, chyba że{ }
użyto jawnego bloku, ale nie zostaną one zainicjowane, ponieważ kod inicjujący należy do innegocase
.W poniższym kodzie, jeśli
foo
jest równe 1, wszystko jest w porządku, ale jeśli jest równe 2, przypadkowo użyjemyi
zmiennej, która istnieje, ale prawdopodobnie zawiera śmieci.Opakowanie skrzynki w wyraźny blok rozwiązuje problem:
Edytować
W celu dalszego rozwinięcia
switch
stwierdzenia są po prostu szczególnie fantazyjnym rodzajemgoto
. Oto analogiczny fragment kodu wykazujący ten sam problem, ale wykorzystującygoto
zamiastswitch
:źródło
Deklaracja nowych zmiennych w instrukcjach przypadków jest przyczyną problemów. Dołączenie wszystkich
case
instrukcji{}
ograniczy zakres nowo zadeklarowanych zmiennych do aktualnie wykonywanej sprawy, która rozwiązuje problem.źródło
Standard C ++ 11 dotyczący przeskakiwania niektórych inicjalizacji
JohannesD podał wyjaśnienie standardów.
C ++ 11 N3337 standardowy projekt 6.7 „Oświadczenie Oświadczenie”, mówi:
Od wersji GCC 5.2 komunikat o błędzie mówi teraz:
do
C na to pozwala: c99 przeszedł wcześniejszą inicjalizację
C99 N1256 standardowy projekt Załącznik I „Wspólne ostrzeżenia” mówi:
źródło
Odpowiedź JohannesD jest poprawna, ale wydaje mi się, że nie jest całkowicie jasne w pewnym aspekcie problemu.
W podanym przez niego przykładzie deklaruje i inicjuje zmienną
i
w przypadku 1, a następnie próbuje jej użyć w przypadku 2. Jego argumentem jest to, że gdyby przełącznik przeszedł prosto do przypadku 2,i
byłby używany bez inicjalizacji, i dlatego istnieje kompilacja błąd. W tym momencie można by pomyśleć, że nie byłoby problemu, gdyby zmienne zadeklarowane w przypadku nigdy nie były używane w innych przypadkach. Na przykład:Można oczekiwać, aby skompilować ten program, ponieważ oba
i
ij
są wykorzystywane wyłącznie wewnątrz sprawach, które je deklarują. Niestety, w C ++ nie kompiluje się: jak wyjaśnił Ciro Santilli 包子 露 宪 六四 六四 事件 法轮功 , po prostu nie możemy skakać docase 2:
, ponieważ pomijałoby to deklarację przy inicjalizacjii
i chociaż wcase 2
ogóle nie używai
, jest to nadal zabronione w C ++.Co ciekawe, z pewnymi korektami (
#ifdef
do#include
odpowiedniego nagłówka, a średnikiem po etykietach, ponieważ etykiety mogą być prowadzone tylko przez oświadczenia i deklaracje nie liczą się jako stwierdzeń w C ), program ten ma kompilacji C:Dzięki internetowemu kompilatorowi, np. Http://rextester.com , możesz szybko spróbować skompilować go jako C lub C ++, używając MSVC, GCC lub Clang. Ponieważ C zawsze działa (pamiętaj tylko o ustawieniu STDIN!), Ponieważ C ++ żaden kompilator tego nie akceptuje.
źródło