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

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

新規登録して質問してみよう
ただいま回答率
85.44%
C++

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

Q&A

解決済

2回答

729閲覧

csvファイルを読み込み、cmdで実行する

shiba_1006

総合スコア3

C++

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

0グッド

0クリップ

投稿2023/04/18 05:38

C++を勉強しています。
csvファイルを読み込むことはできるのですが、カンマを|に変えて、出力幅を同じにするやり方がわかりません。手助けお願いします。
いろいろなことを試しましたが、文字化けしたりうまくcmdで表示されませんでした。

出力したい結果は以下です。
|NO  |氏名 |フリガナ |登校日 |
|407 |山田 太郎|ヤマダ タロウ |2021/04/01|
|408 |山田 次郎 |ヤマダ ジロウ |2021/04/01|
|409 |山田 三郎 |ヤマダ サブロウ |2021/04/01|
|410 |山田 四郎| ヤマダ シロウ |2021/04/01|

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
using namespace std;

int main(int argc, char *argv[]) {

if (argc != 2) { cout << "パラメータ数が違います。" << endl; return 1; } ifstream fin(argv[1]); if (!fin) { cout << "ファイルをオープンできませんでした。" << endl; return 1; } char ch; fin.get(ch); while (!fin.eof()) { cout.put(ch); fin.get(ch); } fin.close(); return 0;

}

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

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

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

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

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

episteme

2023/04/18 05:50

> いろいろなことを試しましたが 呈示されたコードに"いろいろなことを試しました”が見あたりません。
shiba_1006

2023/04/18 06:15

iint i; for(i = 0;!fin.eof(); i++) { string strline; if(getline(fin strline)) { std::stringstream ss(strline); std::string s; while(getline(ss, s, 's')){ cout << "s" << end; } } } このように1行ずつで試してみてもダメでした。そのあとがわからなくなります。
fana

2023/04/18 07:44

> 出力幅を同じにする の意味がわかりません.詳述できないのでしょうか? > 出力したい結果は以下です と示されている物を見ても,一体何が「同じ幅」になっているのかさっぱりわかりません.
shiba_1006

2023/04/18 07:51

出力幅を同じにしたいのは|の部分です。一直線にしたいのです。わかりにくくすみません。
fana

2023/04/18 07:55 編集

たとえば「各列の開始位置が全ての行で揃った形の出力になるように,各要素の末尾に適切にスペースを補わねばならない」だとか,具体的に説明すると良いのでは.(「一直線」にするために,何をすべきなのか? というところまで.)
shiba_1006

2023/04/18 07:54

なるほど、ありがとうございます
fana

2023/04/18 07:59

"|" の位置を全行で揃えるためには,少なくとも「全行の内容を知る」必要がある(1文字読んでは即出力するような処理では無理)と思う. なので,まずはとりあえず「入力を全て読んでデータとして保持する」→「その後,その保持データ全てを表示する」みたいな形をやってみることから始めてはどうか? それで後段の「保持データ全てを表示する」の部分をいろいろと工夫してみるための土台ができるのでは.
shiba_1006

2023/04/18 08:10

class StaffInfo { public: string NO; string NAME; string KANA; string FWORK; void setno(string NO); void setname(string NAME); void setkana(string KANA); void setfwork(string FWORK); }; voidの一番上から、NOを保存名前を保存というように関数を作ったのですが、そのあとの処理に困っています。コードが思いつきません...
fana

2023/04/18 10:40 編集

……というわけで, 「まずはCSVファイルの内容を全て読む → 何やかんや頑張って表示してみる」っていう処理フローな回答を書いてみた. 何か参考にでもなれば. (…とか言ってたら,既に別の質問立ててこっちは放棄されててワラタ)
shiba_1006

2023/04/18 23:53 編集

すみません、説明不足等があったものですから、新しいものを書いたほうが良いと思いました。 回答いただきありがとうございます。 参考にさせていただきます。
guest

回答2

0

ベストアンサー

少しやってみました.

入力ファイルについて

CSV ファイルって,普通は各行の先頭と末尾にはカンマが付かないと思うので,以下のような内容のファイルとしました.
また,ファイル作成に際しては,Windowsの「メモ帳」で文字コードとして「ANSI」を選択して保存しました.(UTF-8 とかにすると,うまく表示する方法がわからないので…^^)

NO  ,氏名 ,フリガナ ,登校日 407 ,山田 太郎,ヤマダ タロウ ,2021/04/01 408 ,山田 次郎 ,ヤマダ ジロウ ,2021/04/01 409 ,山田 三郎 ,ヤマダ サブロウ ,2021/04/01 410 ,山田 四郎, ヤマダ シロウ ,2021/04/01

コード

注釈入れたので特に説明は不要かな,とか思います.

C++

1//Load all lines from CSV File 2std::vector< std::string > LoadCSVFile( const std::string &FilePathName ) 3{ 4 std::vector< std::string > Lines; 5 6 auto File = std::ifstream( FilePathName ); 7 if( File.is_open() ) 8 { 9 std::string Line; 10 while( std::getline( File, Line ) ) 11 { 12 Lines.push_back( Line ); 13 } 14 } 15 return Lines; 16} 17 18//main 19int main() 20{ 21 //Load all lines from CSV File 22 std::vector< std::string > Lines = LoadCSVFile( "input_ANSI.txt" ); 23 if( Lines.empty() ){ std::cout << "Failed to Load CSV File" << std::endl; return 0; } 24 25 {//* Visualize the result of LoadCSVFile() to check. (delete if unnecessary) 26 std::cout << Lines.size() << "Lines.\n"; 27 for( const auto &Line : Lines ){ std::cout << '"' << Line << "\"\n"; } 28 std::cout << std::endl; 29 } 30 31 //Separate all line strings to cell strings (by splitting with comma). 32 //And also decide output width for each column. 33 std::vector< size_t > ColumnWidth; //output width for each column 34 std::vector< std::vector<std::string> > CellStrs; 35 { 36 CellStrs.reserve( Lines.size() ); 37 38 for( auto &Line : Lines ) 39 { 40 //* Add comma to tail to simplify the following process. 41 Line += ','; 42 43 //Splitting work 44 std::vector<std::string> Cells; 45 int CellIndex = 0; 46 std::string::size_type SearchBeginPos = 0; 47 while( SearchBeginPos < Line.size() ) 48 { 49 auto FoundPos = Line.find_first_of( ',', SearchBeginPos ); 50 size_t Length = FoundPos - SearchBeginPos; 51 Cells.push_back( Line.substr( SearchBeginPos, Length ) ); 52 53 if( CellIndex < ColumnWidth.size() ) 54 { ColumnWidth[CellIndex] = std::max( ColumnWidth[CellIndex], Length ); } 55 else 56 { ColumnWidth.push_back( Length ); } 57 58 SearchBeginPos = FoundPos + 1; 59 ++CellIndex; 60 } 61 CellStrs.push_back( Cells ); 62 } 63 } 64 65 //Output 66 for( const auto &Row : CellStrs ) 67 { 68 std::cout << '|'; 69 size_t nCell = std::min( ColumnWidth.size(), Row.size() ); 70 for( size_t iCell=0; iCell<nCell; ++iCell ) 71 { 72 std::cout << Row[iCell]; 73 if( ColumnWidth[iCell] > Row[iCell].size() ) 74 { std::cout << std::string( ColumnWidth[iCell] - Row[iCell].size(), ' ' ); } 75 76 std::cout << '|'; 77 } 78 std::cout << std::endl; 79 } 80 81 return 0; 82}

以下は出力結果です.
(上記コードの25行目付近にある,ファイル読み結果の確認用出力も出ています)

5Lines. "NO  ,氏名 ,フリガナ ,登校日" "407 ,山田 太郎,ヤマダ タロウ ,2021/04/01" "408 ,山田 次郎 ,ヤマダ ジロウ ,2021/04/01" "409 ,山田 三郎 ,ヤマダ サブロウ ,2021/04/01" "410 ,山田 四郎, ヤマダ シロウ ,2021/04/01" |NO  |氏名 |フリガナ |登校日 | |407 |山田 太郎 |ヤマダ タロウ |2021/04/01| |408 |山田 次郎 |ヤマダ ジロウ |2021/04/01| |409 |山田 三郎 |ヤマダ サブロウ |2021/04/01| |410 |山田 四郎 | ヤマダ シロウ |2021/04/01|

投稿2023/04/18 08:57

編集2023/04/18 08:59
fana

総合スコア11729

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

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

fana

2023/04/18 09:09 編集

コード 69行目の std::min での比較は要らないな.単純に size_t nCell = Row.size(); でいい. 入力がスペースを含む場合,特に何もせずに馬鹿正直にそれも1文字として用いている. あと,なんとなく各行の要素数が違ってもいけそうな雰囲気にしてみたつもりなんだけど,空行があると普通にしくじるように思われるw
guest

0

cout.put(ch);


cout.put(ch ==',' ? '|':ch);
に差し替えたらちっとはマシになりませんか?

投稿2023/04/18 05:57

episteme

総合スコア16614

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

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

shiba_1006

2023/04/18 06:10

cout.put(ch ==',' ? '|':ch); どうしたらそういう考えに至るのでしょうか
episteme

2023/04/18 06:25

「読み込んだ文字chが ','なら'|' それ以外はchそのまま」を出力してますが、理解できないことがありますか?
shiba_1006

2023/04/18 06:29

?:の演算子を利用したということでしょうか? == で代入ということでしょうか
episteme

2023/04/18 06:32 編集

> ?:の演算子を利用したということでしょうか? コードから明らかですが、わからないことはありますか? > == で代入ということでしょうか ==は比較演算ですよ? 代入できるんですか?
shiba_1006

2023/04/18 06:34

==は等価でしたすみません
episteme

2023/04/18 06:39

で、期待する結果は得られましたか?
shiba_1006

2023/04/18 06:41

cout.put(ch ==',' ? '|':ch); でカンマは|に置き換わることができました。 しかしながら出力幅が同じにはまだたどり着いてはいません。
episteme

2023/04/18 07:03

> 出力幅が同じにはまだたどり着いてはいません。 これを説明せよ。 「入力と同じ幅」ということなら問題はないはず。
shiba_1006

2023/04/18 07:07

|NO  |氏名 |フリガナ |登校日 | |407 |山田 太郎|ヤマダ タロウ|2021/04/01| |408 |山田 次郎 |ヤマダ ジロウ |2021/04/01| |409 |山田 三郎 |ヤマダ サブロウ |2021/04/01| |410 |山田 五右衛門| ヤマダ ゴエモン |2021/04/01| というに少しずれてしまいます
shiba_1006

2023/04/18 07:08

|が少しずれているのがわかると思います。
episteme

2023/04/18 07:30

それがどうした? 入力は等幅になってるのか? 「入力と同じ幅」ということなら問題はないはず。
shiba_1006

2023/04/18 07:35

入力幅は左寄せになっていますが、cmdでの出力の際に等幅にしたいです
episteme

2023/04/18 07:39

見た目 で | を揃えたいなら等幅フォントで出力すれば?
shiba_1006

2023/04/18 07:59

それをしているのですが、うまくできないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問