質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

Q&A

解決済

5回答

4256閲覧

for文などのループが最後まで回ったかを確認する方法

tuyudaku

総合スコア75

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

0グッド

0クリップ

投稿2019/07/18 00:31

編集2019/07/18 01:26

QSerialPortInfoを使って接続されているシリアルポートデバイスの一覧から
接続したい対象のデバイスを探し出して、見つけたらQSerialPort::openを使ってデバイスと接続する
という処理を行っています。

c++

1 // 接続されているシリアルポートデバイスの一覧から検索。 2 for(const QSerialPortInfo &serial_port: QSerialPortInfo::availablePorts()) 3 { 4 // メーカー名から検索。 5 if("tyometyome" == serial_port.manufacturer()) 6 { 7 device_serial_port_->setPortName(serial_port.portName()); 8 9 if(!device_serial_port_->open(QIODevice::ReadWrite)) 10 { 11 qDebug() << device_serial_port_->error(); 12 device_serial_port_->close(); 13 } 14 else 15 { 16 // 成功 17 } 18 break; 19 } 20 }

この際に、デバイスは見つかったがQSerialPort::openで失敗したのか
単純にデバイスが見つからなかったのかでエラー表示を分けたいなと思ったのですが

素直に実装するならループが最後まで回ったら見つからなかったという処理にすれば良いので
if("tyometyome" == serial_port.manufacturer())に入った時点で適当なフラグを立てればいいと思ったのですが
どこかのサイトで、今時の高級言語であればやたらにフラグを使わずとも大体は実装できる
というような文を見たのを思い出したので

もしかしたら、「ループが最後まで回ったか?」というようなステータスを取得できる処理がC++の標準やQtにあるのでは?
と思ったので質問させてもらいました
自分なりに検索はしてみたのですがそれっぽいものは見当たらなかったで無いのかなとは思ったのですが
最後に皆様に聞いてみようと思い質問させてもらいました

よろしくお願いします。

###追記
コードを修正してみました

C++

1 QList<QSerialPortInfo> port_list = QSerialPortInfo::availablePorts(); 2 3 // 接続されているシリアルポートデバイスの一覧からメーカー名と一致するものを検索 4 auto find_result = std::find_if(port_list.begin(), port_list.end(), [](QSerialPortInfo port){ return "tyometyome" == port.manufacturer(); }); 5 if(port_list.end() == find_result) 6 { 7 // 見つからなかった 8 } 9 else 10 { 11 device_serial_port_->setPortName(find_result->portName()); 12 13 if(!device_serial_port_->open(QIODevice::ReadWrite)) 14 { 15 qDebug() << device_serial_port_->error(); 16 device_serial_port_->close(); 17 } 18 else 19 { 20 // 成功 21 } 22 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

今時の高級言語であればやたらにフラグを使わずとも大体は実装できる

それは「forループで回す」という構造そのものを取らない、という意味ではないかと思います。

今回の場合、まずはじめにstd::find_ifでデバイスを探す、というのがいいかと思います。

投稿2019/07/18 00:44

編集2019/07/18 00:45
maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuyudaku

2019/07/18 01:26

>それは「forループで回す」という構造そのものを取らない、という意味ではないかと思います もっと根本的な部分からだったのですね >今回の場合、まずはじめにstd::find_ifでデバイスを探す、というのがいいかと思います そんな便利なものが... コードを修正してみました、よろしければ評価のほどお願いします 回答ありがとうございました!
guest

0

ベストアンサー

こんにちは。

このケースは私も std::find_if を使うのがスマートと思いますが、std::find_if等のSTLを使えない場合、ラムダ式を使うのも一つです。

C++

1#include <iostream> 2 3bool foo() 4{ 5 static int count=0; 6 return 6 <= ++count; 7} 8 9int main() 10{ 11 bool reachedEnd = []() 12 { 13 for (int i=0; i < 5; ++i) 14 { 15 if (foo()) 16 return false; 17 } 18 return true; 19 }(); 20 21 if (reachedEnd) 22 { 23 std::cout << "Reached the end.\n"; 24 } 25}

wandbox

しかし、C++のラムダ式はキーワードがないので、なかなか読みにくいですね。
フラグ変数を使わないよう if 文の中でラムダ式を呼び出すバージョンもやってみたのですが、止めておいた方が良さそうです。


実は意外にラムダ式とループは相性が良いです。2重ループからの抜け出しは goto を使う、関数へ切り出す、フラグ変数を追加する等しないと無理ですが、関数内で関数を定義するラムダ式なら別のところに関数を定義しなくてもその場でかけるので、短い処理なら見通しがよくなります。

投稿2019/07/18 03:31

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

主題とちょっとズレている気もしますが,

「ループが最後まで回ったか?」というようなステータスを取得できる処理

に関しては,とりあえず古典的な(?)のはこんなですよね.
(別途フラグを用意する必要はない)

const int N = 5; int A[N] = { 1,2,3,4,5 }; //範囲forじゃなくて,自前でiterationのカウンタ(コンテナならばiteratorとか)を扱えばいい int i=0; for( ; i<N; ++i ) { if( A[i]==3 )break; //条件次第で途中で抜ける } std::cout << ( (i<N) ? "最後まで回った" : "途中で抜けた" ) << std::endl;

投稿2019/07/18 02:20

編集2019/07/18 02:22
fana

総合スコア11634

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

std::find_if を利用して、条件に合うものが見つかったらそれに対する処理をする、見つからなかったらその場合の処理を書くというのはいかがでしょうか?

https://cpprefjp.github.io/reference/algorithm/find_if.html

投稿2019/07/18 00:47

tasuku.

総合スコア347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuyudaku

2019/07/18 01:28

>std::find_if を利用して、条件に合うものが見つかったらそれに対する処理をする そんなものがあるなんて知りませんでした! やはり標準ライブラリをどれだけ知っているかでコードの質が変わりますね... コードを修正してみたのでよろしければ評価のほどお願いします 回答ありがとうございました!
guest

0

関数化して戻り値でエラーコードを返すのがいいと思います。

投稿2019/07/18 00:33

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/07/18 00:37

やたらにフラグを使うなというのは、構造化しろという意味だと思います。構造化の進んでいないコードはスパゲッティと呼ばれ、バグの温床となります。この質問のコードの場合は構造化のために関数に切り出すことが最善ではないかと思います。
tuyudaku

2019/07/18 01:21

>やたらにフラグを使うなというのは、構造化しろという意味だと思います なるほど、浅く捉えすぎていたみたいですね... 構造化も意識しつつコードを修正していきたいと思います 回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問