Ich habe ein Programm geschrieben, das die Verwendung von switch-Anweisungen beinhaltet ... Beim Kompilieren zeigt es jedoch:
Fehler: Zum Falletikett springen.
Warum macht es das?
#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
Block in geschweiften Klammern eingeschlossen?Antworten:
Das Problem ist, dass in einem deklarierte Variablen
case
in den folgendencase
s weiterhin sichtbar sind, sofern kein expliziter{ }
Block verwendet wird. Sie werden jedoch nicht initialisiert, da der Initialisierungscode zu einem anderen gehörtcase
.Wenn im folgenden Code
foo
gleich 1 ist, ist alles in Ordnung, aber wenn es gleich 2 ist, verwenden wir versehentlich diei
Variable, die zwar existiert, aber wahrscheinlich Müll enthält.Das Umschließen des Falls in einen expliziten Block löst das Problem:
Bearbeiten
Zum weiteren aufwendigen,
switch
Aussagen sind nur eine besonders ausgefallene Art eingoto
. Hier ist ein analoger Code, der das gleiche Problem aufweist, jedoch eingoto
anstelle einesswitch
:quelle
Die Deklaration neuer Variablen in case-Anweisungen verursacht Probleme. Wenn Sie alle
case
Anweisungen in einschließen,{}
wird der Umfang neu deklarierter Variablen auf den aktuell ausgeführten Fall beschränkt, der das Problem löst.quelle
C ++ 11-Standard zum Überspringen einiger Initialisierungen
JohannesD gab eine Erklärung, jetzt für die Standards.
Der C ++ 11 N3337-Standardentwurf 6.7 "Deklarationserklärung" lautet:
Ab GCC 5.2 lautet die Fehlermeldung jetzt:
C.
C erlaubt es: c99 geht nach der Initialisierung
Der C99 N1256 Standardentwurf Anhang I "Allgemeine Warnungen" lautet:
quelle
Die Antwort von JohannesD ist richtig, aber ich bin der Meinung, dass ein Aspekt des Problems nicht ganz klar ist.
Das Beispiel, das er gibt, deklariert und initialisiert die Variable
i
in Fall 1 und versucht dann, sie in Fall 2 zu verwenden. Sein Argument ist, dass, wenn der Wechsel direkt zu Fall 2 ging,i
ohne Initialisierung verwendet würde, und deshalb gibt es eine Kompilierung Error. An diesem Punkt könnte man denken, dass es kein Problem geben würde, wenn in einem Fall deklarierte Variablen in anderen Fällen niemals verwendet würden. Beispielsweise:Man könnte erwarten, dass dieses Programm kompiliert wird, da beide
i
undj
nur in den Fällen verwendet werden, die sie deklarieren. Leider wird es in C ++ nicht kompiliert: Wie Ciro Santilli erklärte , können wir einfach nicht springencase 2:
, da dies die Deklaration mit der Initialisierung von überspringen würdei
und obwohl siecase 2
überhaupt nicht verwendeti
wird. Dies ist in C ++ immer noch verboten.Interessanterweise mit einigen Anpassungen (ein
#ifdef
auf#include
den entsprechenden Header und ein Semikolon nach den Etiketten, weil Etiketten können nur von Anweisungen folgen, und Erklärungen gelten nicht als Aussagen in C ), ist dieses Programm tut Kompilierung als C:Dank eines Online-Compilers wie http://rextester.com können Sie schnell versuchen, ihn mithilfe von MSVC, GCC oder Clang entweder als C oder C ++ zu kompilieren. Als C funktioniert es immer (denken Sie daran, STDIN zu setzen!), Als C ++ akzeptiert es kein Compiler.
quelle