アプリ版:「スタンプのみでお礼する」機能のリリースについて

forループ内にif文があり,それがtrueであった場合,処理(処理1)後breakでforループを抜けます。ループが完結するまでif文に引っかからないでループを抜けた場合,別の処理(処理2)をしたいのです。しかし,処理1をした場合,処理2はしたくありません。しかし,breakで抜けた後でも処理2が実行されてしまいます。ループ内のif文がtrueの場合,フラグを立てておいて,ループを抜けたところで,そのフラグが立っていたら処理2をしないようにすればできますが,スマートではありません。何かスマートな方法はないものでしょうか。forループ以外のループを使ってもかまいませんが。
具体的には,文字列0がabc.jpgだったら,文字列1(フォルダー名)をNULL,文字列2(ファイル名)をabc.jpgとし,文字列0がc:\dir1\folder1\defgh.jpgだったら文字列1をc:\dir1\folder1\とし,文字列2をdefgh.jpgとする処理をしたいのです。
後ろから\を探していって,見つかったらそこで文字列を分け,最後まで見つからなかったら,文字列1をNULLとし,文字列2を元の文字列にするプログラムを考えました。

質問者からの補足コメント

  • うーん・・・

    neko_deuxさん,コメントありがとうございました。
    No.1のお礼に書いたような一般的な方法を知りたかったのです。実は,具体的な例につきましては,strrchr()を用いて自分では満足行くコードを書くことができました。
    とにかく,forループ内にif文があり,ループの最後に至る前にif文を満足した場合は処理1だけを,ループの間,全くif文を満足しなかった場合処理2だけを実行する方法を知りたいのです。昔だったらgoto文を使っちゃいますがスマートではないですね。

    for(…){
     …
     if(…){
      処理1
      goto A
     }
     …
    }
    処理2
    (ラベルA)

    No.2の回答に寄せられた補足コメントです。 補足日時:2019/09/06 20:40
  • へこむわー

    すみません,No.1のところで,補足に書くべき所をお礼に書いてしまいました。下の補足に書きましたが,strrchrを使って具体例はすでに解決しています。ただ,forループ内のifを満足した時処理1のみ,ifを満足しないでループが完結した時,処理2のみ実行するスマートな方法を知りたいのです。

    No.3の回答に寄せられた補足コメントです。 補足日時:2019/09/06 20:46
  • No.12さんの回答は,「フラグを立てなくても,breakで抜けたか,forループを完結したか判断できるよ」ということでしたか。

    No.12の回答に寄せられた補足コメントです。 補足日時:2019/09/07 14:56

A 回答 (12件中1~10件)

言語によってはそのような機能があったりするけど, C だとどうやっても「いまひとつ」感がある.



一般論だと「フラグを使う」のが普通だと思うけど, なんとなくスマートさに欠ける気もする. あるいは, 状況によってはループの継続条件を使うこともできるけど, これも「同じ条件を複数回書く」のが気持ちわるい.

C++ だと例外を使っても同じようなことができるけど, これも不自然だしねぇ.
    • good
    • 0
この回答へのお礼

コメントありがとうございました。フラグを使うのが一般的なんですね。あとは,forループの前にifに引っかからない場合の処理をしておいて,ループ内でifに引っかかったら処理内容を修正することも考えました。これは,それがフラグを使うより非効率だったら意味がないので,吟味する必要があるとは思います。

お礼日時:2019/09/07 10:48

途中で抜けたのなら、ループ継続条件(for(;;)の2つ目)が真だし、ループ終了で抜けたのなら、ループ継続条件が偽なので、容易に判断つくと思うのですが?



for(p=str1; *p; p++){
if(*p=='\n') break;
)
if(*p) {
printf("改行があった\n");
} else {
printf("改行がなかった\n");
}
この回答への補足あり
    • good
    • 0
この回答へのお礼

コメントありがとうございました。ちょっと論点がずれてしまっていませんでしょうか。

お礼日時:2019/09/07 14:53

>「goto文は安易に使うな」という言葉にしたがった結果,自分としては見やすいプログラムが書けるようになったと感じています。



すいません、余談は、後藤(goto)教授が「goto文は安易に使うな」とおっしゃった点がポイントです。失礼しました
    • good
    • 0
この回答へのお礼

洒落に気づかずお恥ずかしい(^_^" でも,見やすいプログラムになったことは事実です。

お礼日時:2019/09/07 14:25

まだ出てない方法としては、「ループ部分を関数に分ける」でしょうか。


breakの代りにreturnを使います。

void funcA(〜) {
 for(〜) {
  if( 〜 ) {
   処理1
   return ;
  }
 }
 処理2
}

今回の場合だと、「\を探す関数」と「探索結果で処理を分岐」に分けると、だいぶ見栄えがよくなります。
int searchBackslash(〜) {
 for(〜) {
  if( 文字が見付かった ) {
   return 見付かった場所;
  }
 }
 return -1 ; /* 見付からなかったら-1を返す */
}

/*呼び出し側*/
int index ;
...
index = searchBackslash(〜) ;
if (index>=0) {
 処理1
} else {
 処理2
}



なんか「ダサい」のは仕方ないです。
C言語は古い言語なので。
    • good
    • 0
この回答へのお礼

コメントありがとうございました。古い言語にもかかわらず,たくさんの意見をいただけてうれしいです。ご提案の方法も,トータルでの効率を考えながら,今後のプログラミングの参考にさせていただきたいと思います。ありがとうございました。

お礼日時:2019/09/07 11:05

>処理2のみ実行するスマートな方法を知りたいのです。


関数にして、break文をreturn文にする

ラベルAを適切な名前にして goto 文を使う
でも良いと思います

余談
昔、後藤先生の講義で、 goto文は安易に使うな とおっしゃって、学生たちが失笑したことがありましたっけ。
    • good
    • 0
この回答へのお礼

コメントありがとうございました。私のコンピュータ言語のスタートはFORTRANでした。その頃はgo to文の連発で,「スパゲッティプログラム」という言葉があったくらいです。「goto文は安易に使うな」という言葉にしたがった結果,自分としては見やすいプログラムが書けるようになったと感じています。

お礼日時:2019/09/07 11:00

ループがbreakしたかを言語の構文で判定できるのは


pythonしか知らないです。

フラグを使うのが常套手段で、みなそうしますよ。
breakしたという情報が残らないなら作るしかないです。
    • good
    • 0
この回答へのお礼

コメントありがとうございました。いろいろな言語が出てきているのですね。Cが慣れてきているので,なかなか他の言語に手を出すのは抵抗があります。今回の質問も,自分のCをもっとよくしたいという気持ちです。
フラグが一般的と聞きまして,他に方法がない場合はそうしようという気持ちになってきました。

お礼日時:2019/09/07 10:56

No5です。

こちらのほうが、多少まとまっているかも。
#include <stdio.h>
#include <string.h>
int main(void)
{
char str0[] = "c:\\dir1\\folder1\\defgh.jpg";
char str1[256];
char str2[256];
int i;
int x;
for(i = strlen(str0)-1;i>=0;i--){
if (str0[i] == '\\') break;
}
x = i + 1;
strcpy(str1,str0);
str1[x] = '\0';
strcpy(str2,&str0[x]);
printf("<%s>\n",str0);
printf("<%s>\n",str1);
printf("<%s>\n",str2);

return 0;
}
    • good
    • 0
この回答へのお礼

いろいろ考えてくださりありがとうございます。本題とは関係ありませんが,gooでは,元で字下げをしても無視されてしまうのですね。

お礼日時:2019/09/07 10:51

>forループ外でフラグにより処理1,2を分ける(一方はif文内でもかまわない)方法ですね。


>同じifをforループ内と,外で2度やっているようなもので,ちょっと気持ちが悪いのです。
要は処理1、処理2をまとめて、一か所でやりたいということですね。
以下のようにしてはいかがでしょうか。ポイントはxの値です。xの初期値は0にしておきます。
xは文字列2へコピーするときの文字列0の開始位置です。

#include <stdio.h>
#include <string.h>
int main(void)
{
char str0[] = "c:\\dir1\\folder1\\defgh.jpg";
char str1[256];
char str2[256];
int i;
int x = 0;
for(i = strlen(str0)-1;i>=0;i--){
if (str0[i] == '\\'){
x = i + 1;
break;
}
}
strcpy(str1,str0);
str1[x] = '\0';
strcpy(str2,&str0[x]);
printf("<%s>\n",str0);
printf("<%s>\n",str1);
printf("<%s>\n",str2);
return 0;
}
    • good
    • 0
この回答へのお礼

コメントありがとうございました。具体例につきましてはすでに解決しています。ご呈示のxを使う方法は参考になりました。ありがとうございました。

お礼日時:2019/09/07 10:44

No3です。


>ただ,forループ内のifを満足した時処理1のみ,ifを満足しないでループが完結した時,処理2のみ実行するスマートな方法を知りたいのです。

No3にも書きましたが、予め文字列1をNULLクリアしておく方法はいかがでしょうか。

文字列1をNULLクリア
for(){
if (\が文字列0に存在する){
 文字列1を設定
 文字列2を設定
 break
}
}

if (文字列1がNULL){
 処理1
}
のようになるかと。
    • good
    • 0
この回答へのお礼

やはりお礼の所に書いた方が時系列的に見やすいですね。補足の場合は質問の下に表示されるのですね。ですので,お礼の所に書かせていただきます。
文字列のことは忘れてください。すでに解決しているので。本当に知りたいのは「forループ内のif文がtrueだった場合,処理1のみ,if文に一度もヒットしなかった時,処理2のみを行うスマートな方法」ということです。ご提案は基本的にはNo.2のご回答とおなじ,forループ外でフラグにより処理1,2を分ける(一方はif文内でもかまわない)方法ですね。同じifをforループ内と,外で2度やっているようなもので,ちょっと気持ちが悪いのです。

お礼日時:2019/09/06 21:37

No1です。


for文のループとは、文字列0の後ろから¥を探すということですか。
そうであれば、最初に文字列1をNULLに設定しておいてはいかがでしょうか。
\があった場合は、文字列1はNULLでなくなります。
ループを抜けたとき、文字列1がNULLなら、最後まで見つからなかったケースを適用します。

別解ですが、このような場合、\を最後から探す関数があります。
strrchrがありますので、これを使ってみてはいかがでしょうか。
#include <stdio.h>
#include <string.h>
int main(void)
{
char str0[] = "c:\\dir1\\folder1\\defgh.jpg";
char str1[256];
char str2[256];
char *p;
p = strrchr(str0,'\\');
if (p == NULL){
strcpy(str1,"");
strcpy(str2,str0);
}else{
strcpy(str1,str0);
*(str1+(p-str0+1)) = '\0';
strcpy(str2,p+1);
}
printf("<%s>\n",str0);
printf("<%s>\n",str1);
printf("<%s>\n",str2);
return 0;
}
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!