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

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

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

Erlangとは、多目的でありガーベッジコレクションを行うプログラミング言語および実行環境です。Erlangは並行処理・分散化された環境・フォルトトレランスを実装しています。

Q&A

解決済

1回答

1135閲覧

[Erlang] ASCIIコードで表示されてしまう

MaSaKai

総合スコア11

Erlang

Erlangとは、多目的でありガーベッジコレクションを行うプログラミング言語および実行環境です。Erlangは並行処理・分散化された環境・フォルトトレランスを実装しています。

0グッド

0クリップ

投稿2020/03/09 09:22

前提・実現したいこと

初歩的な質問かつ知識不足なのはご了承ください。
適当なテキストファイルをjson形式で新たに作成したい。

発生している問題・エラーメッセージ

sample.txt(図1)というファイルをjson形式に変える過程でsample.json(図2)のようにASCIIコードになってしまう。

[true, #{<<"1">> => 2, <<"array">> => [[[[1]]], #{<<"ab">> => <<"cd">>}, [], #{}, false]}, null]

図1 sample.txt

[ 91, 116, 114, 117, 101, 44, 32, 35, 123, 60, 60, 34, 49, 34, 62, 62, 32, 61, 62, 32, 50, 44, 32, 60, 60, 34, 97, 114, 114, 97, 121, 34, 62, 62, 32, 61, 62, 32, 91, 91, 91, 91, 49, 93, 93, 93, 44, 32, 35, 123, 60, 60, 34, 97, 98, 34, 62, 62, 32, 61, 62, 32, 60, 60, 34, 99, 100, 34, 62, 62, 125, 44, 32, 91, 93, 44, 32, 35, 123, 125, 44, 32, 102, 97, 108, 115, 101, 93, 125, 44, 32, 110, 117, 108, 108, 93 ]

図2 sample.json

該当のソースコード

Erlang

1-module(txt_to_json). 2-author("MaSaKai"). 3-import(jsone, [encode/2]). 4 5%% API 6-export([main/0]). 7%% -compile([all_export]). 8 9main() -> 10 Sentense = readlines("sample.txt"), 11 Data = exchange_json(Sentense), 12 writelines("sample.json", Data). 13 14readlines(FileName) -> 15 {ok, Device} = file:open(FileName, [read]), 16 try get_all_lines(Device) 17 after file:close(Device) 18 end. 19 20get_all_lines(Device) -> 21 case io:get_line(Device, "") of 22 eof -> []; 23 Line -> Line ++ get_all_lines(Device) 24 end. 25 26writelines(FileName, Data) -> 27 case file:write_file(FileName, Data) of 28 ok -> io:format("~s/n", [Data]); 29 {error, Reason} -> Reason 30 end. 31 32exchange_json(Data) -> 33 encode(Data, [{indent, 2}, {space, 1}]).

試したこと

jsone's linkを参考にしつつ、エンコードするデータの形を工夫してみたが求めている結果が得られなかった。

補足情報(FW/ツールのバージョンなど)

Version : V10.6
Editor : Intellij

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

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

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

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

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

guest

回答1

0

ベストアンサー

結論から言うと以下の2つのことをするとうまくいきます。

  1. main/0readlines/1を呼んでいるところを、file:consult/1に置き換える
  2. sample.txtファイルの行末にピリオド.をつける。(つけないとfile:consult/1がsyntax errorを返す)

修正後のmain/0

erlang

1main() -> 2 %% Sentense = readlines("sample.txt"), 3 {ok, Sentense} = file:consult("sample.txt"), 4 Data = exchange_json(Sentense), 5 writelines("sample.json", Data).

file:consult/1はファイルの内容をパースして、Erlangのterm(atom, list, mapなどの値)にして返します(ドキュメント)。一方、readlines/1はファイルの内容を文字列にして返します。

jsoneのサンプルコードを見るとわかりますが、JSONへ変換するデータは以下のようなErlangのtermです。文字列ではありません。

erl

1> Data = [true, #{<<"1">> => 2, <<"array">> => [[[[1]]], #{<<"ab">> => <<"cd">>}, [], #{}, false]}, null].

file:consult/1を使うと、jsoneが期待しているデータが用意できるわけです。

ではなぜjsone:encode/2に文字列を渡すと、以下のようなbinary stringが生成されてしまうのでしょうか?

[ 91, 116, 114, 117, 101,

その理由はErlangの文字列が文字コードのlistだからです。

erl

1%% Erlangのシェルでこういうlistを入力すると 2> [91, 116, 114, 117, 101]. 3"[true" %% 文字列として表示される

jsoneのREADMEに「Data Mapping (Erlang <=> JSON)」というセクションがあります。

それを見ると、Erlangのlist(例:[1,2,3])は、JSONのarray(例:[1,2,3])に変換されることがわかります。つまり、文字列"[true"にあたるlist[91, 116, 114, 117, 101が、JSONの数値のarrayに変換されていたわけです。

投稿2020/03/09 11:17

編集2020/03/09 11:24
tatsuya6502

総合スコア2035

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

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

MaSaKai

2020/03/10 06:14

早急及び丁寧な解答、誠にありがとうございます。原因としては、jsoneの仕様を把握しきれていませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問