#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <time.h> #include <vector> #include <algorithm> #include <map> using namespace std; int main(int argc, char* argv[]) { time_t now = time(nullptr); #if 0 tm nowtm = *localtime(&now); #else tm nowtm; localtime_s(&nowtm, &now); #endif cout << nowtm.tm_year+1900 << "/" << nowtm.tm_mon << "/" << nowtm.tm_mday << endl; cout << nowtm.tm_hour << ":" << nowtm.tm_min << ":" << nowtm.tm_sec << endl; return 0;
新しいExcelではutf-8なCSVのエクスポートができるぞい
やあ子供たち。元気でやっているか。最近おじさんは熱帯魚飼育を始めてみたよ。水が白く濁ってなかなか治らなくてな。まあ何でも勉強で、大変なんだけれども。
さて今日はExcelでutf-8なCSVをエクスポートしたいという内容だよ。(※本記事は、最近までおじさんが知らなかっただけの話だろという側面もありますので見下ろす感じで読んでくれても大丈夫です。)
●旧来からの「CSVとして出力」だとShitftJISになってしまう。
いわゆる環境依存文字、例えば日本語圏以外のマルチバイト文字を含むExcelシートをCSVとしてエクスポートしたい場面は昨今よくあるわけだが、過去これまでのExcelで俺たち日本人なら誰もがやってきた「名前をつけて保存」でCSVとして出力をするやり方だと、文字コードはShiftJIS固定で出力されてしまうので、Excelの中の世界ではちゃんと表示されていたそうした外国系の文字は、CSVに出力した途端に?などがついて、なんとも悲しい文字化けCSVとしての出力しかできなかった。
「日本語をShiftJISのCSVで出力してメモ帳でutf-8にすればええやん」そうじゃない。そういう話をしているのではありません。普通の標準の日本の漢字しか含まれていないExcelシートだったら、もちろんそれでOKで、誰も困らないよ。メモ帳でutf-8化しちゃってくださいそれで話は終わりだよ。
そういうケースではなくて今は、日本語以外の、外国の見たことないような環境文字(或いは日本語でも標準の漢字ではない難しい漢字などが含まれているExcelファイル)の話をしているよ。そういうExcelファイルをCSVに出力する場合の話をしているよ。本来Excelの中でちゃんと表示されていたこれら普段は見ないような環境文字がですね、旧来のExcelでCSVエクスポートすると、ShiftJISになって「潰れて」しまうからこまるよねと、そういう話をしているんだよ坊やわかるかい。
これがために以下のような解決策を右往左往する必要があった。
- UniCodeテキストとして出力 UniCode?。「名前をつけて保存」でUniCode、つまりUTF16テキストとして出力する方法。これはカンマじゃなくてタブ区切りのUTF16テキストとして出力してくれるので、メモ帳などでタブをカンマに置換してutf-8として保存しなおす方法。文字はちゃんと変換されてくれて有難いのだけれども。。けれども罠があって連続する空のカラムがあると区切ってくれるはずのタブを全部まとめて1個のタブとして出力してくれるから列情報がめちゃめちゃになるので、事実上、空のカラムが1個もないとわかってるシートでしか使えなさそう。
●新しいExcelでは、「CSVとして出力(ただしutf-8でな)」が選べる!
はいここからが本題だ。ところがところが上述の心配や努力は一切必要なくなる新機能の登場だ。新しいExcelでは、「名前をつけて保存」の中に、もう普通に「CSVとして出力(ただしutf-8でな)」が、何も考えずに誰でも簡単に!これをやればいいだけなんですみなさん!今日は特別価格で、1万円を切りました!さらにさらに、今ならお得な1年分パックもつけちゃいます!(←最後のはExcelの価格とかじゃないからな。ふざけてるだけだよ。)
はい。みんなも最新のExcelを買って時間や人手をセーブすることを検討してみてはいかがだろうか。
※ていうか、Excelもそんなに最新じゃなくてって話もある。Excel2016あたりから使おうと思えば使えるオプションだったという噂も。最近までおじさんが知らなかっただけの話っていうのは本当にそうなので。
今日のネタは以上でおしまいだよ。チャオ!
HTTP range リクエストも、express.static()にお任せ
やあ子供たち。express.static()は中で、動画はちゃんとストリーミングで配ってくれてるのだろうとかいったあたりの中身に挙動がよくわからなかったので、動画ファイルのリクエスト来た時だけは自前のミドルウェアで捕まえて、単純な自前実装のストリーミング配信実装通すようにしてたら、とあるクライアント環境ではrangeリクエストに対応してないから動画見れないっていうケースのあることに気づいたが、ふと思いついてexpress.static()に任せきりなコードに戻した(つまり自前ミドルウェアを全コメントアウト)ら、その動画見れなかった環境でも問題なく動画見れちゃって、あれ、結局express.static()に任せきりでよかったんだって今日なった話を忘れずにメモしておきたかった。
express.static()の前身は、serv-staticというライブラリだったらしく、serv-staticでは、rangeリクエストへの対応がデフォルトでONになっているみたいな記事を読んでもしやと思ってやってみたらやっぱりそういうことだったのかみたいな。
res.sendFile()について
やあ子供たち。今日はres.sendFile()についてだよ。そうExpressだね。
今日言いたいことは以下の2つだ。
- res.sendFile()が受け取るパスは、express.staticとは関係ない絶対パスである。
- res.sendFile()の後には、res.end()は必要ない!
以上だ。
じゃ今日はこの辺で!チャオ!
findOne()とfindOneAndUpdate()とでは、コールバックに返されるdocの階層が違うので気を付けよう
function(err, doc){
doc; //←findOne()の場合はこれがドキュメントのコピー。
doc.value; // ←findOneAndUpdate()で、updateされた方のドキュメントを受け取るように指定した場合はこれがドキュメントのコピー。docではないので、はまった。
}
そゆこと。簡単にはそゆこと。
socket.ioを使いたいならapp.listen()じゃだめさ
やあ子供たち。express勉強しているか。おじさんは勉強始めたばかりのくせにすぐこんなふうに上から目線のタイトルをつけた記事を書いちゃうんだからな。気を付けてくれよ。
さて今日はapp.listen()を使ってしまうと、socket.ioが使えなくなるという恐ろしい事実を知ったので緊急メモを残すぞ。
const express =require("express"); const app = express(); app.listen(80,()=>{ console.log("app listening.. "); const socketio = require("socket.io"); const io = socketio(server); // emit, on, いくらやっても、、→→使えない! }); io.sockets.on('connection', function (socket) { socket.on("tak",data=>{ }); });
はい、これでサーバは立ち上がるだろうが、これではsocket.ioが使えなくなるんだね。え?エラー?いやいや何も出ないよ。ただソケット通信ができなくなるんだよ。いくらemitしてonで受け取ろうとしてもなしの礫さ。そして何十分も棒に振ることになるんだね。恐ろしいね。
ではどうすればよいか?まあ落ち着け、そうだからってexpressじゃsocket.ioが使えないぜって話でもないんだ。。
それはね、つまりexpress とsocket.io とを組み合わせて使いたい場合はね、以下のようにすることらしいぞ。
const express =require("express"); const app = express(); const http = require("http"); const server = http.createServer(app); server.listen( 80, "127.0.0.1", ()=>{ console.log("app listening.. "); }); const socketio = require("socket.io"); const io = socketio(server); // emit, on, いくらやっても、、→→使える! io.sockets.on('connection', function (socket) { socket.on("tak",data=>{ }); });
はいはい何をしたかというと、app.listen()ではだめで server.listen()を使っていきましょうということらしい。こうすればね、app.useとかapp.getとか普通に使えるしexpress使えるよ、しかもsocket.ioもちゃんと通信できる。
はい、ではなぜなのか。なぜapp.listen()ではだめで server.listen()ならsocket.ioが使えるようになるのか。
このことは本家サイト(●こちら)でも紹介されているが詳細説明はない。
そしてここでも(●リンク)いろいろ頑張ってみた人がいたが、腑に落ちる説明が見当たらない。ここの書込みではこのことをtrapと呼んでいる人もいて(1年前だよそんなに最近なのにね!)この案件は本当にtrapなんだよね。
では今日はこのあたりで。チャオ!