Visual Studioでstd::min()/std::max()がエラーになるときの回避策

C++11からstd::minとstd::maxは複数の引数を受け取ることができるようになりました。

#include <algorithm>

int i = std::min({1, 2, 3, 4});

ところが、Visual Studioで上記のコードを実行するとコンパイルエラーになります。

原因は、windows.hにmin/maxのマクロが定義されているため。

マイクロソフトのページにある解決策は、「NOMINMAXのプリプロセッサシンボルを定義します。」とあります。
しかし、それができない状況もあります。

他の回避策が「windows.hのmin/maxマクロ回避策4パターン – yohhoyの日記」に紹介されていました。

(std::min)(…)や(std::max)(…)のように、括弧で囲みマクロ展開を抑止することで問題を回避できます。

#include <algorithm>

int i = (std::min)({1, 2, 3, 4});

これでエラーにならなくなりました。

JavaScriptのテンプレートエンジン EJS を使う

JavaScriptのテンプレートエンジン EJS の使い方を紹介します。

EJSはJavaScriptで使えるシンプルなテンプレートエンジンです。
高機能ではありませんが、シンプルでわかりやすいライブラリです。

package.jsonの作成

package.jsonファイルを作成します。

npm init

EJSのインストール

EJSをインストールします。

npm install ejs --save

簡単な使い方

EJSを読み込みます。

var ejs = require('ejs');

EJSのテンプレート文字列を用意します。

var str = '<%= params.join(" "); %>';

テンプレートに使用するデータを用意します。

var params = ['Hello', 'world'];

テンプレートエンジンを実行して、作成された文字列を受け取ります。

var html = ejs.render(str, {params: params});

実行結果を確認します。

console.log(html);  //=> Hello world

全体のコードは次のようになります。

var ejs = require('ejs');
var str = '<%= params.join(" "); %>';
var params = ['Hello', 'world'];
var html = ejs.render(str, {params: params});
console.log(html);  //=> Hello world

より高度な使い方は後述。

EJSのタグ

<%= %>

テンプレートの値を出力します。
<と>をエスケープします。

例:現在の日付を国際標準化機構 (ISO) 形式で出力する。

var ejs = require('ejs');
var html = ejs.render(
    '<%= date.toISOString() %>',
    { date: new Date() });

例:<と>をエスケープする

var ejs = require('ejs');
var html = ejs.render(
    '<%= value %>',
    { value: '<h1>Hello world</h1>'});
console.log(html); //=> &lt;h1&gt;Hello world&lt;/h1&gt;

<%- %>

テンプレートの値を出力します。
<と>をエスケープしません。

例:現在の日付を国際標準化機構 (ISO) 形式で出力する。

var ejs = require('ejs');
var html = ejs.render(
    '<%- date.toISOString() %>',
    { date: new Date() });

例:<と>をエスケープしない

var ejs = require('ejs');
var html = ejs.render(
    '<%- value %>',
    { value: '<h1>Hello world</h1>'});
console.log(html); //=> <h1>Hello world</h1>

<% %>

JavaScriptの処理を行います。
出力はしません。

var fruits = ["Apple", "Pear", "Orage", "Lemon"];
<% for(var i = 0; i < fruits.length; ++i) {%>
- <%=fruits[i]%>
<% } %>

例:Array.forEachで繰り返し処理

var ejs = require('ejs');
var tmpl = `<% params.forEach(function(v, i){ %>
<%= i %>:<%= v %>
<% }); %>`;
var html = ejs.render(
    tmpl,
    { params: ['Hello', 'world'] });

例:if分で条件分岐

var ejs = require('ejs');
var tmpl = `
<% if (params.length === 0) { %>
empty
<% } %>
`;

var html = ejs.render(
    tmpl,
    { params: [] });

高度な使い方

テンプレートをファイルから読み込む

renderFile()関数を使用します。

var ejs = require('ejs');
var filename = './tmpl.ejs'; // ファイル名
var params = { date: new Date() }; // 引数
var html = ejs.renderFile(filename, params, function(err, str) {
    console.log(str);
});

またはinclude()関数を使用します。
この場合はオプションにfilenameを指定します。

var ejs = require('ejs');
var html = ejs.render(
    '<%- include("./tmpl.ejs", date); %>',
    { date: new Date() },
    { filename: "./tmpl.ejs" });

テンプレートの入れ子

テンプレートの中に、別のテンプレートを組み込む方法です。

var ejs = require('ejs');

var main_tmpl = `MainData = <%- maindata %>
<%- sub %>`;

var sub_tmpl = `SubData = <%- subdata %>`;

var html = ejs.render(
    main_tmpl,
    {
        maindata: 'MAINDATA',
        sub: ejs.render(sub_tmpl,
            { subdata: 'SUBDATA' })
    }
);

JavaScriptで画像のサイズを調べる

image-size」を使うと、簡単に画像のサイズを調べることができました。

単機能でわかりやすく、使いやすいライブラリでした。

インストール

image-sizeをインストールします。

npm install image-size --save

画像のサイズを調べる

サンプルコードです。
TypeScriptで書いています。

import * as sizeOf from "image-size";
const dimensions = sizeOf("sample.jpg");
console.log(`width=${dimensions.width},height=${dimensions.height}`);

非同期処理も用意されています。

import * as sizeOf from "image-size";
sizeOf("sample.jpg", (err, dimensions) => {
    console.log(`width=${dimensions.width},height=${dimensions.height}`);
});

対応しているファイル形式

Supported formats

  • BMP
  • GIF
  • JPEG
  • PNG
  • PSD
  • TIFF
  • WebP
  • SVG

TSLintの導入手順

package.jsonを作成する

package.jsonを作成する

npm init

tslintをインストールする

npm install tslint --save-dev

設定ファイル tslint.json を作成する

tslint --init

または

node .\node_modules\tslint\bin\tslint --init

tslintでプログラムをチェックする

tslint myapp.ts

または

node .\node_modules\tslint\bin\tslint myapp.ts

node.jsでCSVファイルを読み込むには

node-csvを使って、CSVファイルを読み込む方法です。

node-csvでCSVファイルを読み込む

まずはインストール。

npm install csv --save

sample.csvを読み込み、コンソールに出力します。

const fs = require('fs');
const parse = require('csv').parse;

const parser = parse((err, data) => console.log(data));

fs.createReadStream(__dirname + '/sample.csv').pipe(parser);

CSVファイルの文字コードがUTF-8のときは正しく表示されました。

しかし、Shift_JISのファイルはときは文字化けしました。

iconv-liteで文字コードを変換する

Shift_JISのファイルを読み込むことができるように、iconv-liteをインストールします。

npm install csv --save

iconv-liteを使って、Shift_JISのCSVファイルを読み込みます。

const fs = require('fs');
const parse = require('csv').parse;
const iconv = require('iconv-lite');

const parser = parse((err, data) => console.log(data));

fs.createReadStream(__dirname + '/sample.csv')
    .pipe(iconv.decodeStream('shift_jis'))
    .pipe(parser);

正しく読み込めました。

CSVファイルのデータを文字列の配列として取得する

読み込んだCSVファイルのデータは、parser中のdataに入っています。
dataが各行の配列になっており、各行はセルの値の文字列の配列になっています。

const fs = require('fs');
const csv = require('csv');

const parser = csv.parse((err, data) => {
    console.log('CSVファイルの行数=' + data.length);
    data.forEach((element, index, array) => console.log(index + '行目=' + element));
});

fs.createReadStream(__dirname + '/sample.csv').pipe(parser);

CSVファイルのデータをオブジェクトの配列として取得する

オプションに{columns:true}をつけると、1行目をプロパティ名にしたオブジェクトの配列が返ります。

TypeScriptのサンプルコード。

import * as fs from "fs";
import * as csv from "csv";

fs.readFile(__dirname + "/sample.csv", (err, data) => {
    // オプションに{columns:true}をつけると、1行目をプロパティ名にしたオブジェクトの配列が返る
    csv.parse(data, { columns: true }, (err, output: Array<Object>) => {
        output.forEach((value) => { console.log(value); });
    });
});

samle.csv

abc,def,ghi
123,456,789
ABC,DEF,GHI

実行結果

{ abc: '123', def: '456', ghi: '789' }
{ abc: 'ABC', def: 'DEF', ghi: 'GHI' }

C++で16進数・10進数・8進数を変換するには

数値を16進数の文字列に変換する

    std::stringstream ss;
    ss << std::hex << 16777215;
    std::cout << ss.str() << std::endl; //=> ffffff

数値を8進数の文字列に変換する

    std::stringstream ss;
    ss << std::oct << 16777215;
    std::cout << ss.str() << std::endl; //=> 77777777

16進数の文字列を数値に変換する

    int n;
    std::istringstream("ffffff") >> std::hex >> n;
    std::cout << n << std::endl; //=> 16777215

8進数の文字列を数値に変換する

    int n;
    std::istringstream("77777777") >> std::oct >> n;
    std::cout << n << std::endl; //=> 16777215

Windows版Visual Studio Code 1.9.0でターミナルをPowerShellからcmd.exeに変更するには

Windows版Visual Studio Code 1.9.0で「Ctrl+@」キーを押して統合ターミナルを開くと、cmd.exeでなくPowerShellになっていました。

cmd.exeを使用するには、次の設定を行います。

  1. メニューの「ファイル」→「基本設定」→「ユーザー設定」を選択して、設定ファイルを開きます。

  2. 次のコードを追加します。

    “terminal.integrated.shell.windows”: “C:\WINDOWS\Sysnative\cmd.exe”

楽天商品情報CSV化ソフトを公開しました

楽天商品情報CSV化ソフトを公開しました。

概要

楽天商品情報CSV化ソフト、はRMSの商品一覧ページから商品情報を取得して、CSVファイルに保存するソフトです。

アプリケーションに組み込まれているブラウザを自動操作して、商品ページから情報を取得します。

商品情報は、「商品個別更新 変更」ページから取得します。
項目選択肢別在庫などは取得しません。今回は必要なかったので。

商品情報の読み込みだけで書き込みは行いません。
ソフトに不具合があったとしても、商品情報が消えたり、書き換わったりすることはありません。

フリーソフトです。無料でご利用いただけます。

使い方

  1. アプリケーション(RakutenItemCSV.exe)を起動します。

  2. R-Loginのログイン画面が表示されたら、R-Loginにログインします。

  3. ログインしたら、RMSの「1-1.商品登録・更新」→「商品一覧」を選択します。

  4. 「商品種別から選択」の「通常」を選択します。

  5. 商品一覧が表示されたら、「開始」ボタンを押します。

  6. 商品一覧情報を保存するCSVファイルのファイル名を入力します。

  7. 「保存」ボタンを押すと、商品一覧情報の取得処理が始まります。 処理が終わると、ステータスバーに「終了しました。」と表示されます。

動作環境

  • Windows Vista
  • Windows 7
  • Windows 8
  • Windows 10

Windows 10以外では動作確認していません。
たぶん動作すると思います。

インストール

ダウンロードしたファイルを展開してください。

アンインストール

ファイル一式を削除してください。

レジストリは使用していません。

ダウンロード

ダウンロードはこちら

CSVファイル

CSVファイルの1行目は列名になっています。
列名は商品ページのHTMLの入力欄のname属性を使用しています。

各列は次の通りです。

  • mng_number

    商品管理番号(商品url)

  • item_number

    商品番号

  • item_name

    商品名

  • catch_copy

    pc用キャッチコピー

  • mobile_catch_copy

    モバイル用キャッチコピー

  • price

    販売価格

  • dual_price_id

    二重価格文言id

    0.自動選択
    1.当店通常価格
    2.メーカー希望小売価格
    4.商品価格ナビのデータ参照

  • regular_price_type

    表示価格

    1.表示価格
    2.オープン価格

  • regular_price

    二重価格文言

  • tax_flag

    消費税

    0.消費税別
    1.消費税込

  • postage_flag

    送料

    0.送料別
    1.送料無料

  • soryo_kbn1

    送料区分1

  • soryo_kbn2

    送料区分2

  • postage

    個別送料

  • daibiki_flag

    代引料

    0.代引料別
    1.代引料込

  • noshi_flag

    のし対応

    0.対応しない
    1.対応する

  • sell_flag

    注文ボタン

    0.ボタンをつけない
    1.注文ボタンをつける
    2.予約ボタンをつける

  • release_date_year

    予約商品発売日(年)

  • release_date_month

    予約商品発売日(月)

  • release_date_day

    予約商品発売日(日)

  • panf_flag

    資料請求ボタン

    0.ボタンをつけない
    1.ボタンをつける

  • ask_flag

    問い合わせボタン

    0.ボタンをつけない
    1.ボタンをつける

  • stock_notify_flag

    再入荷お知らせボタン

    0.ボタンをつけない
    1.ボタンをつける

  • sale_stime_year

    販売開始日時(年)

  • sale_stime_month

    販売開始日時(月)

  • sale_stime_day

    販売開始日時(日)

  • sale_stime_hour

    販売開始日時(時)

  • sale_stime_min

    販売開始日時(分)

  • sale_etime_year

    販売終了日時(年)

  • sale_etime_month

    販売終了日時(月)

  • sale_etime_day

    販売終了日時(日)

  • sale_etime_hour

    販売終了日時(時)

  • sale_etime_min

    販売終了日時(分)

  • units_type

    注文受付数

    1.自由入力
    2.非表示(最大個数1個)
    3.最大購入数を設定

  • units

    最大購入数

  • inventory_type

    在庫タイプ

    0.在庫設定しない
    1.通常在庫設定
    2.項目選択肢別

  • inventory

    在庫数

  • nokori

    在庫表示

    -1.在庫設定しない
    0.残り在庫数表示しない
    1.残り在庫数表示する

  • restore_inventory_flag

    在庫戻し設定

  • backorder_flag

    在庫切れになっても注文を受け付ける

  • normal_delvdate_id

    在庫あり時の納期

    1.2~3日以内に発送します
    2.ご注文後、1週間以内にお届けします。
    3.ご注文後、2週間程度でお届けします。
    4.毎月 月末に入荷します。
    1000.1~2日以内に発送予定(店舗休業日を除く)

  • catalog_caption

    PC用商品説明文

  • mobile_caption

    モバイル用商品説明文

  • smart_caption

    スマートフォン用商品説明文

  • display_caption

    PC用販売説明文

  • image_url1

    商品画像(1)URL

  • image_alt1

    商品画像(1)名称ALT

  • image_url2

    商品画像(2)URL

  • image_alt2

    商品画像(2)名称ALT

  • image_url3

    商品画像(3)URL

  • image_alt3

    商品画像(3)名称ALT

  • image_search_url

    白背景画像

  • movie_url

    動画

  • genre_id

    全商品ディレクトリID

  • tag_id

    タグID

  • rcatalogid_type

    カタログIDの有無

    1.あり
    2.なし

  • rcatalog_id

    カタログID

  • catalogId_exemption_reason

    カタログIDなしの理由

    1.セット商品
    2.サービス商品
    3.店舗オリジナル商品
    4.項目選択肢在庫商品
    5.該当製品コードなし

  • plural_item_page

    表示先カテゴリラジオボタン

  • category_1

    表示先カテゴリ1

  • category_2

    表示先カテゴリ2

  • category_3

    表示先カテゴリ3

  • category_4

    表示先カテゴリ4

  • category_5

    表示先カテゴリ5

  • item_weight

    店舗内カテゴリでの表示順位

  • limited_flag

    サーチ非表示

  • limited_passwd

    闇市パスワード

  • depot_flag

    倉庫指定

    0.販売中
    1.倉庫に入れる

  • ha_name

    項目選択肢別在庫用横軸項目名

  • va_name

    項目選択肢別在庫用縦軸項目名

  • inventory_disp_type

    項目選択肢別在庫用残り表示閾値

    0.在庫設定しない
    1.在庫数を表示
    2.在庫数を表示しない

  • inventory_disp

    在庫数が個以下になったら「△」の印を表示する

免責事項

このプログラムの使用により生じたいかなる損害についても保障することは出来ません。

サポート

本ソフトウェアについては、メールでのみサポートを受け付けています。

使い方がわからないときは、気軽にお問い合わせください。

ご意見、ご感想お待ちしています。

Yahoo!Japanの爆速YQLを使って、ブログのRDFから更新情報一覧を表示する

以前に「Google Feed APIの代替手段と設定方法」で、RSSから更新情報を取得して、更新情報一覧を表示する方法を紹介しました。

今回は、RSSの代わりにRDFから更新情報を取得するサンプルコードです。

RDFは、このブログのPDFを使用しました。

  • http://www.gesource.jp/weblog/?feed=rdf

コードはこのようになります。

<script
  src="http://i.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
  data-url="http://www.gesource.jp/weblog/"
  data-p-feed="rdf">
    {{#query.results.RDF.item}}
    <ul>
    <li><a href="{{link}}">{{title}}</a></li>
    </ul>
    {{/query.results.RDF.item}}
</script>

実行結果です。↓

↑ブログの最新のエントリーが表示されていれば成功です。

FileNameNormalizer ファイル名正規化ソフト 0.1.0を公開しました

WindowsとmacOSではファイル名の付け方が異なります。
たとえば「が」という文字は、Windowsでは「が」の1文字ですが、macOSでは「か」+「゛」(濁点)の2文字で構成されます。

macOSで作成したファイルをWindowsで受け取ったとき、このファイル名の付け方の違いによって、アプリによっては問題が発生することがあります。

そこで、ファイル名やフォルダー名をWindowsの流儀に変換するソフトウェアを作成しました。

使い方は簡単です。

ファイル名を変換したいファイルをドラッグアンドドロップでアプリに追加します。
あとは「リネーム開始」ボタンを押すと、ファイル名が変換されます。

ファイル名以外にも、フォルダー名も変換できます。

個人的なアプリですので、アイコンやヘルプなどは用意していませんが、利用者が増えれば改善していきます。