我有一个程序需要用户输入4个文件(无需订单)。然后我对文件做了不同的事情。现在我使用goto语句,我想替换goto语句,但不知道如何。我想知道这些是否有问题?这是我使用goto的代码:
int main(int argc, char **argv){
char *tmp;
int i, flag1=0, flag2=0, flag3=0, flag4=0;
FILE *fp1;
FILE *fp2;
FILE *fp3;
FILE *fp4;
char file1[64];
char file2[64];
char file3[64];
char file4[64];
for( i=1; i<argc; i++){
tmp = argv[i];
if ( strcmp(tmp+8,"F1") == 0 ){
sprintf(file1,argv[i]);
flag1=1;
}
else if (strcmp(tmp+8,"F2") == 0 ){
sprintf(file2,argv[i]);
flag2=1;
}
else if (strcmp(tmp+8,"F3") == 0 ){
sprintf(file3,argv[i]);
flag3=1;
}
else if (strcmp(tmp+8,"F4") == 0 ){
sprintf(file4,argv[i]);
flag4=1;
}
}
if( !(flag1 && flag2 && flag3 && flag4) ){
printf("Must input four files!!\n");
exit(-1);
}
if (access(file1,0) != 0){
GOTO L1;
}
if((fp1 = fopen(file1,"r")) == NULL){
exit(-1);
}
do_file_1(fp1);
fclose(fp1);
L1: if (access(file2,0) != 0 ){
goto L2;
}
if((fp2 = fopen(file2,"r")) == NULL){
exit(-1);
}
do_file_2(fp2);
fclose(fp2);
L2: if (access(file3,0) != 0)
{
goto L3;
}
if((fp3=fopen(file3,"r"))==NULL)
{
exit(-1);
}
do_file_3(fp3);
fclose(fp3);
L3: if (access(file4,0) !=0)
{
goto end;
}
if((fp4=fopen(file4,"r"))==NULL)
{
exit(-1);
}
do_file_4(fp4);
fclose(fp4);
end:
return 0;
}
答案 0 :(得分:2)
你有&#34;如果这个条件为真,请跳过一些代码&#34;。这是您ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-darwin14]
============================================================
Running tests for obj = 1000000 (Fixnum)
user system total real
obj: 0.970000 0.000000 0.970000 ( 0.987204)
nil_obj: 0.980000 0.010000 0.990000 ( 0.980796)
obj.nil?: 1.250000 0.000000 1.250000 ( 1.268564)
nil_obj.nil?: 1.280000 0.000000 1.280000 ( 1.287800)
!obj: 1.050000 0.000000 1.050000 ( 1.064061)
!nil_obj: 1.070000 0.000000 1.070000 ( 1.170393)
!!obj: 1.110000 0.000000 1.110000 ( 1.122204)
!!nil_obj: 1.120000 0.000000 1.120000 ( 1.147679)
obj == nil: 2.110000 0.000000 2.110000 ( 2.137807)
nil_obj == nil: 1.150000 0.000000 1.150000 ( 1.158301)
obj != nil: 2.980000 0.010000 2.990000 ( 3.041131)
nil_obj != nil: 1.170000 0.000000 1.170000 ( 1.203015)
============================================================
Running tests for obj = 100000.0 (Float)
user system total real
obj: 0.940000 0.000000 0.940000 ( 0.947136)
nil_obj: 0.950000 0.000000 0.950000 ( 0.986488)
obj.nil?: 1.260000 0.000000 1.260000 ( 1.264953)
nil_obj.nil?: 1.280000 0.000000 1.280000 ( 1.306817)
!obj: 1.050000 0.000000 1.050000 ( 1.058924)
!nil_obj: 1.070000 0.000000 1.070000 ( 1.096747)
!!obj: 1.100000 0.000000 1.100000 ( 1.105708)
!!nil_obj: 1.120000 0.010000 1.130000 ( 1.132248)
obj == nil: 2.140000 0.000000 2.140000 ( 2.159595)
nil_obj == nil: 1.130000 0.000000 1.130000 ( 1.151257)
obj != nil: 3.010000 0.000000 3.010000 ( 3.042263)
nil_obj != nil: 1.170000 0.000000 1.170000 ( 1.189145)
============================================================
Running tests for obj = false (FalseClass)
user system total real
obj: 0.930000 0.000000 0.930000 ( 0.933712)
nil_obj: 0.950000 0.000000 0.950000 ( 0.973776)
obj.nil?: 1.250000 0.000000 1.250000 ( 1.340943)
nil_obj.nil?: 1.270000 0.010000 1.280000 ( 1.282267)
!obj: 1.030000 0.000000 1.030000 ( 1.039532)
!nil_obj: 1.060000 0.000000 1.060000 ( 1.068765)
!!obj: 1.100000 0.000000 1.100000 ( 1.111930)
!!nil_obj: 1.110000 0.000000 1.110000 ( 1.115355)
obj == nil: 1.110000 0.000000 1.110000 ( 1.121403)
nil_obj == nil: 1.100000 0.000000 1.100000 ( 1.114550)
obj != nil: 1.190000 0.000000 1.190000 ( 1.207389)
nil_obj != nil: 1.140000 0.000000 1.140000 ( 1.181232)
============================================================
Running tests for obj = true (TrueClass)
user system total real
obj: 0.960000 0.000000 0.960000 ( 0.964583)
nil_obj: 0.970000 0.000000 0.970000 ( 0.977366)
obj.nil?: 1.260000 0.000000 1.260000 ( 1.265229)
nil_obj.nil?: 1.270000 0.010000 1.280000 ( 1.283342)
!obj: 1.040000 0.000000 1.040000 ( 1.059689)
!nil_obj: 1.070000 0.000000 1.070000 ( 1.068290)
!!obj: 1.120000 0.000000 1.120000 ( 1.154803)
!!nil_obj: 1.130000 0.000000 1.130000 ( 1.155932)
obj == nil: 1.100000 0.000000 1.100000 ( 1.102394)
nil_obj == nil: 1.130000 0.000000 1.130000 ( 1.160324)
obj != nil: 1.190000 0.000000 1.190000 ( 1.202544)
nil_obj != nil: 1.200000 0.000000 1.200000 ( 1.200812)
============================================================
Running tests for obj = string (String)
user system total real
obj: 0.940000 0.000000 0.940000 ( 0.953357)
nil_obj: 0.960000 0.000000 0.960000 ( 0.962029)
obj.nil?: 1.290000 0.010000 1.300000 ( 1.306233)
nil_obj.nil?: 1.240000 0.000000 1.240000 ( 1.243312)
!obj: 1.030000 0.000000 1.030000 ( 1.046630)
!nil_obj: 1.060000 0.000000 1.060000 ( 1.123925)
!!obj: 1.130000 0.000000 1.130000 ( 1.144168)
!!nil_obj: 1.130000 0.000000 1.130000 ( 1.147330)
obj == nil: 2.320000 0.000000 2.320000 ( 2.341705)
nil_obj == nil: 1.100000 0.000000 1.100000 ( 1.118905)
obj != nil: 3.040000 0.010000 3.050000 ( 3.057040)
nil_obj != nil: 1.150000 0.000000 1.150000 ( 1.162085)
============================================================
Running tests for obj = (?-mix:\w) (Regexp)
user system total real
obj: 0.930000 0.000000 0.930000 ( 0.939815)
nil_obj: 0.960000 0.000000 0.960000 ( 0.961852)
obj.nil?: 1.270000 0.000000 1.270000 ( 1.284321)
nil_obj.nil?: 1.260000 0.000000 1.260000 ( 1.275042)
!obj: 1.040000 0.000000 1.040000 ( 1.042543)
!nil_obj: 1.040000 0.000000 1.040000 ( 1.047280)
!!obj: 1.120000 0.000000 1.120000 ( 1.128137)
!!nil_obj: 1.130000 0.000000 1.130000 ( 1.138988)
obj == nil: 1.520000 0.010000 1.530000 ( 1.529547)
nil_obj == nil: 1.110000 0.000000 1.110000 ( 1.125693)
obj != nil: 2.210000 0.000000 2.210000 ( 2.226783)
nil_obj != nil: 1.170000 0.000000 1.170000 ( 1.169347)
唯一使用的内容。
这正是goto
的作用(如果条件为假,则if
跳过代码除外)。
您可以替换:
if
使用:
L2: if (access(file3,0) != 0)
{
goto L3;
}
if((fp3=fopen(file3,"r"))==NULL)
{
exit(-1);
}
do_file_3(fp3);
fclose(fp3);
L3:
,类似于if (access(file3,0) == 0)
{
if((fp3=fopen(file3,"r"))==NULL)
{
exit(-1);
}
do_file_3(fp3);
fclose(fp3);
}
的其他用途。
答案 1 :(得分:2)
你分步重构。
您可以使用结束标签语句并将其直接放在调用它的位置。这很容易。
对于其他人,您可以使用else语句:
if (access(file1,0) != 0){
//GOTO L1;
}else{
if((fp1 = fopen(file1,"r")) == NULL){
exit(-1);
}
do_file_1(fp1);
fclose(fp1);
}
L1: if (access(file2,0) != 0 ){
//goto L2;
}else{
if((fp2 = fopen(file2,"r")) == NULL){
exit(-1);
}
do_file_2(fp2);
fclose(fp2);
}
L2: if (access(file3,0) != 0)
{
//goto L3;
}else{
if((fp3=fopen(file3,"r"))==NULL)
{
exit(-1);
}
do_file_3(fp3);
fclose(fp3);
}
L3: if (access(file4,0) !=0)
{
end:
return 0;
}
if((fp4=fopen(file4,"r"))==NULL)
{
exit(-1);
}
do_file_4(fp4);
fclose(fp4);
当然,由于if语句中没有其他语句,if else
可以重构为if
。
我已经解决了更复杂的问题,例如in the past。
答案 2 :(得分:1)
也许像下面那样使用带数组的循环的方法会更短,更紧凑。这是一个相当简单的转换,将单独的变量合并到数组中。这确实使用了一组函数指针(参见How do Function pointers in C work)。
do_file_1()
,do_file_2()
等功能只是您正在使用的实际功能的占位符。这会保留您指定的文字文件名(&#34; F1&#34;,&#34; F2&#34;等),但我不确定您为什么需要某些特定的文件名。
我还使用strcpy()
函数将文件名参数复制到文件名数组中,而不是使用sprintf()
函数。
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
void do_file_1 (FILE *fp)
{
printf ("function do_file_1 called.\n");
}
void do_file_2 (FILE *fp)
{
printf ("function do_file_2 called.\n");
}
void do_file_3 (FILE *fp)
{
printf ("function do_file_3 called.\n");
}
void do_file_4 (FILE *fp)
{
printf ("function do_file_4 called.\n");
}
int main(int argc, char **argv)
{
int i;
char *fileArray[4] = { "F1", "F2", "F3", "F4"};
char fname[4][64] = {0};
void (*funcs[4]) (FILE *fp) = {do_file_1, do_file_2, do_file_3, do_file_4};
for( i = 1; i < argc; i++) {
int j;
for (j = 0; j < 4; j++) {
if ( strcmp(argv[i], fileArray[j]) == 0 ) {
strcpy(fname[j],argv[i]);
break;
}
}
}
if( !(fname[0][0] && fname[1][0] && fname[2][0] && fname[3][0]) ) {
printf("Must input four files!!\n");
exit(-1);
}
for (i = 0; i < 4; i++) {
if (access(fname[i],0) == 0) {
FILE *fp = fopen(fname[i],"r");
if (fp != NULL) {
funcs[i](fp);
fclose(fp);
} else {
break;
}
} else {
break;
}
}
if (i < 4) exit(-1);
return 0;
}
答案 3 :(得分:0)
明显的变体是改变if这样的陈述:
if (access(file1,0) == 0){
if((fp1 = fopen(file1,"r")) == NULL) exit(-1);
do_file_1(fp1);
fclose(fp1);
}
if (access(file2,0) == 0 ){
if((fp2 = fopen(file2,"r")) == NULL) exit(-1);
do_file_2(fp2);
fclose(fp2);
}
...
答案 4 :(得分:0)
您只是使用goto作为反转if
子句的方法。直接反转它们并缩进它们之间的内容:
if (access(file1,0) != 0){
GOTO L1;
}
if((fp1 = fopen(file1,"r")) == NULL){
exit(-1);
}
do_file_1(fp1);
fclose(fp1);
L1: ...
变为:
if (access(file1,0) == 0)
{
if((fp1 = fopen(file1,"r")) == NULL){
exit(-1);
}
do_file_1(fp1);
fclose(fp1);
}
//L1:
答案 5 :(得分:0)
int main(int argc, char **argv){
char *tmp;
int i, flag1=0, flag2=0, flag3=0, flag4=0;
FILE *fp1;
FILE *fp2;
FILE *fp3;
FILE *fp4;
char file1[64];
char file2[64];
char file3[64];
char file4[64];
for( i=1; i<argc; i++){
tmp = argv[i];
if ( strcmp(tmp,"F1") == 0 ){
sprintf(file1,argv[i]);
flag1=1;
}
else if (strcmp(tmp,"F2") == 0 ){
sprintf(file2,argv[i]);
flag2=1;
}
else if (strcmp(tmp,"F3") == 0 ){
sprintf(file3,argv[i]);
flag3=1;
}
else if (strcmp(tmp,"F4") == 0 ){
sprintf(file4,argv[i]);
flag4=1;
}
}
if( !(flag1 && flag2 && flag3 && flag4) ){
printf("Must input four files!!\n");
return -1;
}
if (access(file1,0) == 0) {
if((fp1 = fopen(file1,"r")) == NULL){
return -1;
}
do_file_1(fp1);
fclose(fp1);
}
/*L1:*/
if (access(file2,0) == 0 ) {
if((fp2 = fopen(file2,"r")) == NULL){
return -1;
}
do_file_2(fp2);
fclose(fp2);
}
/*L2:*/
if (access(file3,0) == 0) {
if((fp3=fopen(file3,"r"))==NULL) {
return -1;
}
do_file_3(fp3);
fclose(fp3);
}
/* L3: */
if (access(file4,0) == 0) {
if((fp4=fopen(file4,"r"))==NULL) {
return -1;
}
do_file_4(fp4);
fclose(fp4);
}
return 0;
}
但实际上,没有一个程序员不会这样做。