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

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

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

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

Q&A

解決済

2回答

6993閲覧

VC++ ofstreamでテキスト出力されない

robomoco

総合スコア31

C++

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

0グッド

0クリップ

投稿2019/05/08 14:10

編集2019/05/08 15:32

以下のプログラムをエラーなく,コンパイルすることができました。が,ofstreamのオブジェクトofsに<<を用いて文字列を出力しても,開いたファイルには何も書きこまれませんでした。全く原因が分かりません。

何故か、Main.cppの下部にあるwhile(1)以降のところをコメントアウトしたら、Code Writerクラスのコンストラクタで定義した、デバッグ用の ofs<<"Open Wow”が実行されて、出力ファイルに上手くか囲まれました。
#Main.cpp

C++

1#include <iostream> 2#include "Parser.h" 3#include "CodeWriter.h" 4using namespace std; 5int main() 6{ 7 Parser parser; 8 CodeWriter codewriter(parser); 9 parser.advance(); 10 while (1) { 11 if (parser.commandType() == C_ARITHMATIC) { 12 codewriter.writeArithmatic(parser.arg1()); 13 } 14 else if (parser.commandType() == C_POP) { 15 codewriter.writePushPop(C_POP, parser.arg1(), parser.arg2()); 16 } 17 else if (parser.commandType() == C_PUSH) { 18 codewriter.writePushPop(C_PUSH, parser.arg1(), parser.arg2()); 19 } 20 parser.advance(); 21 } 22} 23

#Parser.h

C++

1#pragma once 2#include <fstream> 3#include <sstream> 4#include <string> 5#include <iostream> 6enum comType{ 7 C_ERROR, 8 C_ARITHMATIC, 9 C_PUSH, 10 C_POP, 11 C_LABEL, 12 C_GOTO, 13 C_IF, 14 C_FUNCTION, 15 C_RETURN, 16 C_CALL 17}; 18 19class Parser { 20public: 21 std::string infilename; 22 Parser(); //読みこみファイルを開く 23 void advance(); //次のコマンドを読みこむ 24 comType commandType(); //コマンドのタイプを返す 25 std::string arg1(); //現コマンドの1番目の引数を返す 26 int arg2(); //現コマンドの2番目の引数を返す 27 std::ifstream ifs; 28 std::string curcmd; //現在コマンド 29};

#Parser.cpp

C++

1#include "Parser.h" 2using namespace std; 3//クラスParserの実装 4Parser::Parser() 5{ 6 cin >> infilename; 7 ifs.open(infilename); 8 while(ifs.fail()) { 9 cin >> infilename; 10 ifs.open(infilename); 11 } 12} 13 14void Parser::advance() 15{ 16 getline(ifs, curcmd); 17 18 while (curcmd[0] == ' ') { 19 curcmd.erase(curcmd.begin()+0); 20 } 21 while (curcmd[0] == '/') { 22 advance(); 23 } 24 while (curcmd[0] == '\0') { 25 advance(); 26 } 27} 28 29comType Parser::commandType() 30{ 31string curcmdope = curcmd; 32 curcmdope = curcmdope.substr(0, curcmd.find(" ")); 33 if (curcmdope == "add" || curcmdope == "sub" || curcmdope == "neg" || 34 curcmdope == "eq" || curcmdope == "qt" || curcmdope == "lt" || 35 curcmdope == "and" || curcmdope == "or" || curcmdope == "not") { 36 37 return C_ARITHMATIC; 38 } 39 else if (curcmdope == "push") { 40 return C_PUSH; 41 } 42 else if (curcmdope == "pop") { 43 return C_POP; 44 } 45 else { 46 return C_ERROR; 47 } 48} 49 50string Parser::arg1() 51{ 52 string curcmdarg1 = curcmd; 53 54 if (commandType() == C_RETURN) { 55 cout << "C_RETURNは呼ぶな" << endl; 56 return curcmd; 57 } 58 else if (commandType() == C_ARITHMATIC) { 59 return curcmd; 60 } 61 else if (commandType() == C_PUSH || commandType() == C_POP) { 62 63 while (curcmdarg1[0] != ' ') { 64 curcmdarg1.erase(curcmdarg1.begin() + 0); 65 } 66 while (curcmdarg1[0] == ' ') { 67 curcmdarg1.erase(curcmdarg1.begin() + 0); 68 } 69 70 curcmdarg1 = curcmdarg1.substr(0, curcmdarg1.find(" ")); 71 72 return curcmdarg1; 73 } 74} 75 76int Parser::arg2() 77{ 78 string curcmdarg2 = curcmd; 79 80 if (commandType() == C_PUSH || commandType() == C_POP || 81 commandType() == C_FUNCTION || commandType() == C_CALL) { 82 83 while (curcmdarg2[0] != ' ') { 84 curcmdarg2.erase(curcmdarg2.begin() + 0); 85 } 86 while (curcmdarg2[0] == ' ') { 87 curcmdarg2.erase(curcmdarg2.begin() + 0); 88 } 89 while (curcmdarg2[0] != ' ') { 90 curcmdarg2.erase(curcmdarg2.begin() + 0); 91 } 92 while (curcmdarg2[0] == ' ') { 93 curcmdarg2.erase(curcmdarg2.begin() + 0); 94 } 95 curcmdarg2 = curcmdarg2.substr(0, curcmdarg2.find(" ")); 96 //cout << "curcmdarg2 " << curcmdarg2 << endl; 97 return stoi(curcmdarg2); 98 } 99} 100

#CodeWriter.h

C++

1#pragma once 2#include <fstream> 3#include <sstream> 4#include <string> 5#include <iostream> 6 7class CodeWriter { 8public: 9 std::string outfilename; 10 CodeWriter(Parser& parser); //出力先ファイルを開く 11 void setFileName(std::string fileName); 12 int label_num; 13 std::string get_new_label(); 14 void writeArithmatic(std::string command); 15 void writePushPop(comType command, std::string segment, int index); 16 void close(); 17 std::ofstream ofs; 18 //std::string* curcmd; //現在コマンド 19};

#CodeWriter.cpp

C++

1#include "Parser.h" 2#include "CodeWriter.h" 3 4using namespace std; 5 6CodeWriter::CodeWriter(Parser& parser) 7{ 8 label_num = 0; 9 //curcmd = &(parser.curcmd); 10 outfilename = parser.infilename; 11 outfilename.erase(outfilename.find(".") + 1, outfilename.find(".") + 3); 12 outfilename += "hack"; 13 ofs.open(outfilename); 14 ofs << "open WOW"; 15} 16 17void CodeWriter::setFileName(string fileName) 18{ 19 20} 21 22 23 24void CodeWriter::writePushPop(comType command, string segment, int index) 25{ 26 string idx = to_string(index); 27 string outfilename_ex_hack = outfilename; 28 outfilename_ex_hack=outfilename_ex_hack.erase(outfilename.find("."), outfilename.find(".") + 5); 29 cout << "outfilename(-hack): " << outfilename_ex_hack << endl; 30 31 if (command == C_PUSH) { 32 if (segment == "static") { 33 ofs << "@" << outfilename_ex_hack << "." << idx << "\n"; 34 ofs << "D=M\n"; 35 //write push from D-register 36 ofs << "@SP\n"; 37 ofs << "A=M\n"; 38 ofs << "M=D\n"; 39 ofs << "@SP\n"; 40 ofs << "M=M+1\n"; 41 } 42 else if (segment == "constant") { 43 ofs << "@" << idx << "\n"; 44 ofs << "D=A\n"; 45 //write push from D-register 46 ofs << "@SP\n"; 47 ofs << "A=M\n"; 48 ofs << "M=D\n"; 49 ofs << "@SP\n"; 50 ofs << "M=M+1\n"; 51 } 52 else if (segment == "local" || segment == "argument" || 53 segment == "this" || segment == "that") { 54 string reg_name; 55 //write push from virtual segment 56 if (segment == "local") reg_name = "LCL"; 57 else if (segment == "argument")reg_name = "ARG"; 58 else if (segment == "this")reg_name = "THIS"; 59 else if (segment == "that")reg_name = "THAT"; 60 ofs << "@" << reg_name << "\n"; 61 ofs << "A=M\n"; 62 for (int i(0); i < index; i++) { 63 ofs << "A=A+1\n"; 64 } 65 ofs << "D=M\n"; 66 //write push from D-register 67 ofs << "@SP\n"; 68 ofs << "A=M\n"; 69 ofs << "M=D\n"; 70 ofs << "@SP\n"; 71 ofs << "M=M+1\n"; 72 } 73 else if (segment == "pointer" || segment == "temp") { 74 ofs << "@0\n"; 75 if (segment == "pointer") { 76 for (int i(0); i < 3 + index; i++) { 77 ofs << "A = A + 1\n"; 78 } 79 ofs << "D=M\n"; 80 //write push from D-register 81 ofs << "@SP\n"; 82 ofs << "A=M\n"; 83 ofs << "M=D\n"; 84 ofs << "@SP\n"; 85 ofs << "M=M+1\n"; 86 } 87 else if (segment == "temp") { 88 for (int i(0); i < 5 + index; i++) { 89 ofs << "A = A + 1\n"; 90 } 91 ofs << "D=M\n"; 92 //write push from D-register 93 ofs << "@SP\n"; 94 ofs << "A=M\n"; 95 ofs << "M=D\n"; 96 ofs << "@SP\n"; 97 ofs << "M=M+1\n"; 98 } 99 } 100 101 } 102 else if (command == C_POP) { 103 if (segment == "static") { 104 //write pop to m_register 105 ofs << "@SP\n"; 106 ofs << "M=M-1\n"; 107 ofs << "A=M\n"; 108 ofs << "D=M\n"; 109 ofs << "@" << outfilename_ex_hack << "." << idx << "\n"; 110 ofs << "M=D\n"; 111 } 112 else if (segment == "local" || segment == "argument" || 113 segment == "this" || segment == "that") { 114 string reg_name; 115 //write pop to virtual segment 116 if (segment == "local") reg_name = "LCL"; 117 else if (segment == "argument")reg_name = "ARG"; 118 else if (segment == "this")reg_name = "THIS"; 119 else if (segment == "that")reg_name = "THAT"; 120 //write pop to m_register 121 ofs << "@SP\n"; 122 ofs << "M=M-1\n"; 123 ofs << "A=M\n"; 124 ofs << "D=M\n"; 125 ofs << "@" << reg_name << "\n"; 126 ofs << "M=D\n"; 127 } 128 else if (segment == "temp" || segment == "pointer") { 129 //write pop to static segment 130 if (segment == "temp") { 131 132 //write pop to m_register 133 ofs << "@SP\n"; 134 ofs << "M=M-1\n"; 135 ofs << "A=M\n"; 136 ofs << "D=M\n"; 137 ofs << "@0\n"; 138 for (int i(0); i < 3 + index; i++) { 139 ofs << "A=A+1\n"; 140 } 141 ofs << "M=D"; 142 143 } 144 else if (segment == "pointer") { 145 //write pop to m_register 146 ofs << "@SP\n"; 147 ofs << "M=M-1\n"; 148 ofs << "A=M\n"; 149 ofs << "D=M\n"; 150 ofs << "@0\n"; 151 for (int i(0); i < 5 + index; i++) { 152 ofs << "A=A+1\n"; 153 } 154 ofs << "M=D"; 155 } 156 } 157 } 158} 159 160string CodeWriter::get_new_label() { 161 label_num += 1; 162 return "LABEL"+to_string(label_num); 163} 164void CodeWriter::writeArithmatic(string command) 165{ 166 if (command == "add") { 167 //write pop to m_register 168 ofs << "@SP\n"; 169 ofs << "M=M-1\n"; 170 ofs << "A=M\n"; 171 ofs << "D=M\n"; 172 //write pop to m_register 173 ofs << "@SP\n"; 174 ofs << "M=M-1\n"; 175 ofs << "A=M\n"; 176 177 ofs << "D=D+M\n"; 178 179 //write push from D_register 180 ofs << "@SP\n"; 181 ofs << "A=M\n"; 182 ofs << "M=D\n"; 183 ofs << "@SP\n"; 184 ofs << "M=M+1\n"; 185 } 186 else if (command == "sub") { 187 //write pop to m_register 188 ofs << "@SP\n"; 189 ofs << "M=M-1\n"; 190 ofs << "A=M\n"; 191 ofs << "D=M\n"; 192 //write pop to m_register 193 ofs << "@SP\n"; 194 ofs << "M=M-1\n"; 195 ofs << "A=M\n"; 196ofs << "D=M-D\n"; 197 198 //write push from D_register 199 ofs << "@SP\n"; 200 ofs << "A=M\n"; 201 ofs << "M=D\n"; 202 ofs << "@SP\n"; 203 ofs << "M=M+1\n"; 204 } 205 else if (command == "and") { 206 //write pop to m_register 207 ofs << "@SP\n"; 208 ofs << "M=M-1\n"; 209 ofs << "A=M\n"; 210 ofs << "D=M\n"; 211 //write pop to m_register 212 ofs << "@SP\n"; 213 ofs << "M=M-1\n"; 214 ofs << "A=M\n"; 215 216 ofs << "D=D&M\n"; 217 218 //write push from D_register 219 ofs << "@SP\n"; 220 ofs << "A=M\n"; 221 ofs << "M=D\n"; 222 ofs << "@SP\n"; 223 ofs << "M=M+1\n"; 224 } 225 226} 227 228void CodeWriter::close() 229{ 230 ofs.close(); 231}

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

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

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

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

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

Chironian

2019/05/08 14:15

CodeWriter.cppを貼り付けそこなっているようですよ。
guest

回答2

0

こんにちは。

可能性としては、「while(1)以降のところ」で何か異常が発生してプログラムが落ちていることが考えられます。この場合、CodeWriterのコンストラクタで書き込まれたものはまだキャッシュに残っていてファイルへ出力されていないため、書き込まれないです。
しかし、その部分をコメントアウトして異常終了しなければ、ofsがきちんとデストラクトされるのでその時点でキャッシュの内容はファイルへ書き込まれます。

本当にそうなっているのかどうか確認するには、デバッガを使ってステップ実行するなどしてデバッグした方が良いと思います。

他に、要所要所で、std:cout << "デバッグ文字列" << std::endl;するのも手です。
std::endlは改行だけでなくキャッシュに溜まっているデータをファイルへ追い出すので、落ちたところを見つけやすいです。

投稿2019/05/08 17:16

Chironian

総合スコア23272

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

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

0

自己解決

自己解決しました。
おそらく,while(1)としたのがまずかったのでしょう。無限ループで終わらないので,そこでエラーが発生して,一切のファイル出力をしてくれなかったのものと思われます。多分。
そこで,getline関数を含むadvance()の実装を以下のように,エラー判定できるように変えました。

bool Parser::advance()
{
if(!getline(ifs, curcmd)) return false; <======変更点

while (curcmd[0] == ' ') { curcmd.erase(curcmd.begin()+0); } while (curcmd[0] == '/') { advance(); } while (curcmd[0] == '\0') { advance(); }

}

そしてmain.cppのほうでは,while(1)ではなく,while(parser.advance())とすることで,無限ループを食い止めます。

投稿2019/05/08 17:11

robomoco

総合スコア31

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問