Escribí un programa que implica el uso de declaraciones de cambio ... Sin embargo, en la compilación muestra:
Error: salta a la etiqueta del caso.
¿Porque hace eso?
#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
bloque entre llaves?Respuestas:
El problema es que las variables declaradas en una
case
siguen siendo visibles en las siguientescase
s a menos que se use un{ }
bloque explícito , pero no se inicializarán porque el código de inicialización pertenece a otracase
.En el siguiente código, si
foo
es igual a 1, todo está bien, pero si es igual a 2, usaremos accidentalmente lai
variable que sí existe pero que probablemente contenga basura.Ajustar el caso en un bloque explícito resuelve el problema:
Editar
Para más detalles, las
switch
declaraciones son solo un tipo particularmente elegante de agoto
. Aquí hay un código analógico que muestra el mismo problema pero que usa un engoto
lugar de unswitch
:fuente
La declaración de nuevas variables en declaraciones de casos es lo que causa problemas. El encerrar todas las
case
declaraciones{}
limitará el alcance de las variables recientemente declaradas al caso en ejecución que resuelve el problema.fuente
C ++ 11 estándar al saltar sobre algunas inicializaciones
JohannesD dio una explicación, ahora para los estándares.
El borrador estándar C ++ 11 N3337 6.7 "Declaración de declaración" dice:
A partir de GCC 5.2, el mensaje de error ahora dice:
C
C lo permite: c99 pasa a la inicialización
El borrador estándar del C99 N1256 Anexo I "Advertencias comunes" dice:
fuente
La respuesta de JohannesD es correcta, pero creo que no está del todo claro sobre un aspecto del problema.
El ejemplo que da declara e inicializa la variable
i
en el caso 1, y luego trata de usarla en el caso 2. Su argumento es que si el cambio pasara directamente al caso 2,i
se usaría sin inicializarse, y es por eso que hay una compilación error. En este punto, uno podría pensar que no habría problema si las variables declaradas en un caso nunca se usaran en otros casos. Por ejemplo:Uno podría esperar que este programa para compilar, ya que ambos
i
, yj
sólo se utilizan dentro de los casos que se declaran. Desafortunadamente, en C ++ no se compila: como explicó Ciro Santilli 包子 露 宪 六四 事件 法轮功 , simplemente no podemos saltarcase 2:
, porque esto omitiría la declaración con la inicialización dei
, y aunquecase 2
no se usai
en absoluto, Esto todavía está prohibido en C ++.Curiosamente, con algunos ajustes (una
#ifdef
a#include
la cabecera apropiada, y un punto y coma después de las etiquetas, ya que las etiquetas sólo pueden ser seguidas por declaraciones y declaraciones no cuentan como las declaraciones en C ), este programa hace de compilación como C:Gracias a un compilador en línea como http://rextester.com , puede intentar compilarlo rápidamente como C o C ++, utilizando MSVC, GCC o Clang. Como C siempre funciona (¡solo recuerda configurar STDIN!), Como C ++ ningún compilador lo acepta.
fuente