Q:

C言語で複数のファイルを開くときのエラー処理

C言語で複数のファイルを開いて使う処理を書く場合、
エラー処理はどのように書くのがきれいでしょうか。 
以下のような形を考えましたが、2つ目のファイルオープンで
エラーになったときの処理が気持ち悪いです。 
int func1(char *fname1, char *fname2)
{
    FILE *fp1;
    FILE *fp2;

    if((fp1 = fopen(fname1, "w")) == NULL)
    {
        fprintf(stderr, "fname1 open error.\n");
        return -1;
    }
    if((fp2 = fopen(fname2, "w")) == NULL)
    {
        fprintf(stderr, "fname2 open error.\n");
        fclose(fp1);    //ここが気持ち悪い
        return -1;
    }
    int ret;
    ret = func2(fp1, fp2);  //ファイルに書き込む処理
    fclose(fp1);
    fclose(fp2);
    if(ret ! = 0)
    {
        fprintf(stderr, "error occured in func2.\n");
        return -1;
    }
    return 0;
}

A:

こういう場合では goto を使うと綺麗に書けるので、使用して問題なければ以下のように書くのはどうでしょうか？ 
int func1(char *fname1, char *fname2)
{
    int r = 0;    // 返り値に使用
    FILE *fp1 = NULL;
    FILE *fp2 = NULL;

    if((fp1 = fopen(fname1, "w")) == NULL)
    {
        fprintf(stderr, "fname1 open error.\n");
        r = -1;
        goto cleanup;
    }
    if((fp2 = fopen(fname2, "w")) == NULL)
    {
        fprintf(stderr, "fname2 open error.\n");
        r = -1;
        goto cleanup;
    }
    int ret;
    ret = func2(fp1, fp2);  //ファイルに書き込む処理
    if(ret ! = 0)
    {
        fprintf(stderr, "error occured in func2.\n");
        r = -1;
        goto cleanup;
    }

cleanup:
    if(fp1 ! = NULL){
        fclose(fp1);
    }
    if(fp2 ! = NULL){
        fclose(fp2);
    }
    return r;
}

A:

私もgoto使いますが、どんなパターンでもgoto使うの禁止っていう残念職場ならこう書きます。 
FILE *fp1 = fopen(fname1, "w");
FILE *fp2 = fopen(fname2, "w");

if(fp1 == NULL || fp2 == NULL)
{
    (fp1 == NULL) ?  fprintf(stderr, "fname1 open error.\n") : fclose(fp1);
    (fp2 == NULL) ?  fprintf(stderr, "fname2 open error.\n") : fclose(fp2);
    return -1;
}

// ファイル処理
･･･

fclose(fp1);
fclose(fp2);

