物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

文字型と整数型の上限値と下限値、各データ型のサイズ

参照: ATLAS Japan C++ Course -- Lesson 2

サンプルコード1

#include <iostream>
#include <cstdint>

using namespace std;
int main(int argc, char** argv) {

    cout 
        << "char min. = " << int(INT8_MIN)
        << " max. = " << int(INT8_MAX) << endl
        << "short int min. = " << INT16_MIN
        << " max. = " << INT16_MAX << endl
        << "long int min. = " << INT32_MIN
        << " max. = " << INT32_MAX << endl
        << "long long int min. = " << INT64_MIN
        << " max. = " << INT64_MAX << endl;

    cout 
        << "unsigned char max. = " << int(UINT8_MAX) << endl
        << "unsigned short int max. = " << UINT16_MAX << endl
        << "unsigned long int max. = " << UINT32_MAX << endl
        << "unsigned long long int max. = " << UINT64_MAX << endl;

    return 0;
}

サンプルコード2

#include <iostream>
#include <cstdint>

using namespace std;
int main(int argc, char** argv) {

    cout
        << "bytes of char = " << sizeof(char) << endl
        << "bytes of short = " << sizeof(short) << endl
        << "bytes of int = " << sizeof(int) << endl
        << "bytes of long = " << sizeof(long long) << endl;

    return 0;
}

(解決済み)Windowsの設定を変更するとき1回目にしばらく動作を受け付けなくなる

[解決済み] バージョンを1709にするとこの問題は解消されました。アップグレードしましょう。

Windowsを再起動した後、Windowsの設定を操作するときに一定時間(数十秒)ほど設定ができなくなる。

例えば、アクションセンターを開き、画面の輝度を変更しようとしたとする。

一回目は明るさを変更するためのボタン「おすすめ/明るい」などが表示されるが、それをクリックしても反応はなく、再度アクションセンターを開くと明るさを変更するためのボタン等がすべて表示されない。数十秒経ってからアクションセンターを開くと、ボタンが表示され、輝度の変更ができるようになる。

この、何か設定を変更しようとする→設定変更できず設定のボタンが消える→数十秒後に復活してその他全ての設定が即座に変更可能になる。

というのが、明るさを変更するためのボタンだけでなく、Wi-Fiの設定、Bluetooth、電源の設定を含めた、様々なもので起きる。

Pocoで複数のPoco::Threadを管理してみる

筆者は世に出すサンプルコードのことを甘く見ているので、こんなコードではダメだということに気づかれた方は、お手数でもコメントにお書きください。よろしくお願いいたします。

Visual Studio 2013 は中途半端にC++11が実装されており、スレッドまわりの全ての機能を使うことができない。 そこで、 Poco::Thread を使おうと考えた。

今回は、stlstd::vector で複数のPoco::Threadを管理する。例えば、Poco::Thread を複数作ることを許容し、その上限数を管理しする場合に使える。

#include <iostream>
#include <vector>

#include <Poco/Thread.h>
#include <Poco/Runnable.h>
#include <Poco/ErrorHandler.h>

class HeavyWorker : public Poco::Runnable
{
public:
    int i;
private:
    void run()
    {
        Sleep(1000);
        std::cout << "おわった id=" << i << std::endl;
        //throw std::exception();
    }
};

//例外クラス
class MyHandler : public Poco::ErrorHandler {

public:
    virtual void exception(const Poco::Exception& exc) {
        std::cout << "Poco Exception: " << exc.displayText() << std::endl;
    }
    virtual void exception(const std::exception& exc) {
        std::cout << "std::exception: " << exc.what() << std::endl;
    }
    virtual void exception() {
        std::cout << "Other exception" << std::endl;
    }
};

int main() {
    MyHandler handler;
    Poco::ErrorHandler::set(&handler);


    // スレッド管理用のベクタ
    std::vector<Poco::Thread*> vthread;
    // ワーカー管理用のベクタ
    std::vector<HeavyWorker*> vworker;
    int maxNumThread = 4;

    for (int i = 0; i < 20; i++) {

        while (true) {
            if (vthread.size() < maxNumThread) { break; }
            for (int i = 0; i < vthread.size(); i++) {
                if (vthread[i]->tryJoin(1)) {
                    delete vworker[i];
                    vworker.erase(vworker.begin() + i);
                    delete vthread[i];
                    vthread.erase(vthread.begin() + i);
                    i--;
                }
            }
        }
        std::cout << "現在のスレッド数" << vthread.size() << std::endl;

        Poco::Thread *thread = new Poco::Thread();
        HeavyWorker *worker = new HeavyWorker();
        worker->i = i;
        vworker.emplace_back(worker);
        thread->start(*worker);
        vthread.emplace_back(thread);
        Sleep(100);
    }
    for (int i = 0; i < vthread.size(); i++) {
        vthread[i]->join();
        delete vworker[i];
        vworker.erase(vworker.begin() + i);
        delete vthread[i];
        vthread.erase(vthread.begin() + i);
        i--;
        std::cout << "現在のスレッド数" << vthread.size() << std::endl;
    }
    //std::cin.get();
    return 0;
}

出力例

現在のスレッド数0
現在のスレッド数1
現在のスレッド数2
現在のスレッド数3
おわった id=0
現在のスレッド数3
おわった id=1
現在のスレッド数3
おわった id=2
現在のスレッド数3
おわった id=3
現在のスレッド数3
おわった id=4
現在のスレッド数3
おわった id=5
現在のスレッド数3
おわった id=6
現在のスレッド数3
おわった id=7
現在のスレッド数3
おわった id=8
現在のスレッド数3
おわった id=9
現在のスレッド数3
おわった id=10
現在のスレッド数3
おわった id=11
現在のスレッド数3
おわった id=12
現在のスレッド数3
おわった id=13
現在のスレッド数3
おわった id=14
現在のスレッド数3
おわった id=15
現在のスレッド数3
おわった id=16
現在のスレッド数3
おわった id=17
現在のスレッド数2
おわった id=18
現在のスレッド数1
おわった id=19
現在のスレッド数0

参照

Class Poco::Thread

http://www.digi-con.co.jp/tech/node/180

POCO::Foundationでデザインパターン - マルチスレッド編 - (1/3):CodeZine(コードジン)

テキストファイルの読み取りと、JSONファイルの書き出し・読み取り方

picojson.h は https://github.com/kazuho/picojson/blob/master/picojson.h からダウンロードすべし。

#include "picojson.h"
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

//テキストファイルの読み取り
inline std::string read_txt(std::string const& path)
{
    std::ifstream ifs(path);
    std::stringstream buffer;
    buffer << ifs.rdbuf();
    std::string str = buffer.str();
    // UTF-8のBOM付きをチェック
    if (str.size() >= 3 && str[0] == -17 && str[1] == -69 && str[2] == -65)  return str.substr(3);
    else  return str;
}


//picojson::object型でJSONファイルの読み取り
picojson::object read_json_obj(std::string path)
{
    std::ifstream ifs(path);
    if (!ifs)
    {
        throw std::exception("File cannot be opened.");
    }

    std::string json = read_txt(path);
    picojson::value val;
    std::string err;
    picojson::parse(val, json.c_str(), json.c_str() + strlen(json.c_str()), &err);
    if (!err.empty())
    {
        throw std::exception("JSON format error in");
    }
    return val.get<picojson::object>();
}

//読み取りのサンプル
void read_sample()
{
    auto obj = read_json_obj("file.json");
    auto nog = obj.at("Nogs").get<picojson::array>();
    for (int j = 0; j < nog.size(); j++)
    {
        std::cout << nog[j].get<double>() << " ";
    }
    std::cout << std::endl;
}

//書き出しのサンプル
void write_sample() {
    picojson::object obj;
    picojson::array arr;
    arr.emplace_back(picojson::value(1.0));
    arr.emplace_back(picojson::value(2.0));
    arr.emplace_back(picojson::value(3.0));
    obj["Nogs"] = picojson::value(arr);
    std::ofstream ofs("file.json");
    ofs << picojson::value(obj).serialize(true) << std::endl;
}

//書き出しのサンプル 配列版
void write_sample2() {
    picojson::array arr;
    arr.emplace_back(picojson::value(1.0));
    arr.emplace_back(picojson::value(2.0));
    arr.emplace_back(picojson::value(3.0));
    std::ofstream ofs("file_arr.json");
    ofs << picojson::value(arr).serialize(true) << std::endl;
}

int main() {
    write_sample();
    read_sample();
    return 0;
}

こういう内容のファイルが読み書きされる

{
  "Nogs": [
    1,
    2,
    3
  ]
}

期待される出力

1.00000 2.00000 3.00000

デバッグしてないので取り扱いに注意して下さい。

メンバーが存在しているかの確認は、find()を使って行うと良い。

if (input.find("member") != input.end()) {
    std::cout << "find" << std::endl;
}
else {
    std::cout << "not find" << std::endl;
}

Visual Studio の Cross Tools / Native Toolsって何?

  • x86_x64 Cross Tools Command Prompt for VS 2017
    32bit パソコンで64bit パソコン用の実行ファイルを作る
    ただし、64bitパソコンでも動く

  • x64 Native Tools Command Prompt for VS 2017
    64bit パソコンで 64bit パソコン用の実行ファイルを作る

  • x64_x86 Cross Tools Command Prompt for VS 2017
    64bit パソコンで 32bit パソコン用の実行ファイルを作る

  • x86 Native Tools Command Prompt for VS 2017
    32bit パソコンで 32bit パソコン用の実行ファイルを作る
    ただし、64bitパソコンでも動く

普段は ただし の文は無視してもらってかまわない。64bitマシンでも WOW64 というサブシステムのおかげで32bit パソコン用の実行ファイルが動くからである。

参照

方法: 64 ビットの Visual C++ ツールセットをコマンド ラインから有効にする | Microsoft Docs

WOW64 - Wikipedia

f:id:onsanai:20170723013559p:plain