add: function checkaligned, format the arg, clean code

This commit is contained in:
kuoi 2023-03-20 14:45:56 +08:00
parent 5a337fd47a
commit b038025948
2 changed files with 329 additions and 271 deletions

47
README.md Normal file
View file

@ -0,0 +1,47 @@
# MiMi
```
l、 . . . .
(゚、 。 |\/|*|\/|*
l ~ヽ | ||| ||
じしf_,) | ||| ||
Morphology into Molecules into
GPL Guoyi Zhang, 2023
```
## Functions
Convert any formats listed in `Accepted formats` to each other.
## Arguments
- -h --help;
- -i --input ${filename};
- -o --output ${filename};
## Accepted formats
- fas fasta
- nex nexus
- phy phylip
- tnt ss
## Compile
```
g++ main.cpp -o mimi
```
## License
You should note that the license is (GPL)[https://www.gnu.org/licenses/gpl-3.0.html].
## Acknowledgements
Thanks to my beloved daughter MiMi (Ragdoll cat) for accompanying me in my life, mom loves you forever.

531
main.cpp
View file

@ -1,33 +1,30 @@
#include <iostream> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <algorithm>
using namespace std; using namespace std;
class Basic_arg{ class Basic_arg {
public: public:
int intype=0, outype=0; int intype = 0, outype = 0;
char *itn, *otn; char *itn, *otn;
Basic_arg(int intype, int outype, char* itn, char *otn): Basic_arg(int intype, int outype, char* itn, char* otn)
intype(intype), outype(outype), : intype(intype), outype(outype), itn(itn), otn(otn){};
itn(itn), otn(otn)
{};
}; };
class Sample { class Sample {
public: public:
unsigned ntax, nchar; unsigned ntax, nchar;
string *taxas, *chars; string *taxas, *chars;
Sample(unsigned ntax, unsigned nchar): Sample(unsigned ntax, unsigned nchar) : ntax(ntax), nchar(nchar) {
ntax(ntax), nchar(nchar) { taxas = new string[ntax];
taxas = new string[ntax]; chars = new string[ntax];
chars = new string[ntax]; };
};
}; };
Basic_arg procargs (int nargs, char ** arg, char* itn, char* otn); Basic_arg procargs(int nargs, char** arg, char* itn, char* otn);
Sample read_input(char* itn, int intype); Sample read_input(char* itn, int intype);
void show_help(int help_num); void show_help(int help_num);
Sample readFas(char* itn); Sample readFas(char* itn);
@ -47,52 +44,55 @@ string checktype(string str);
int countfre(string str, char c); int countfre(string str, char c);
int checkextension(string str); int checkextension(string str);
Sample readPhy(char* itn){ Sample readPhy(char* itn) {
//read file // read file
ifstream matrixfile; ifstream matrixfile;
matrixfile.open(itn); matrixfile.open(itn);
//read number of taxa and charcter // read number of taxa and charcter
string sntax, snseq, snall; string sntax, snseq, snall;
getline(matrixfile,snall); getline(matrixfile, snall);
istringstream istr(snall); istringstream istr(snall);
istr >> sntax; istr >> snseq; istr >> sntax;
istr >> snseq;
int ntax, nchar; int ntax, nchar;
ntax = stoi (sntax); nchar = stoi (snseq); // string to int ntax = stoi(sntax);
nchar = stoi(snseq); // string to int
Sample sam(ntax, nchar); Sample sam(ntax, nchar);
//read sequence // read sequence
int lennum; int lennum;
for(lennum=0;lennum<sam.ntax;lennum++){ for (lennum = 0; lennum < sam.ntax; lennum++) {
getline(matrixfile,snall); getline(matrixfile, snall);
istringstream istr(snall); istringstream istr(snall);
istr >> sam.taxas[lennum]; istr >> sam.chars[lennum]; istr >> sam.taxas[lennum];
istr >> sam.chars[lennum];
} }
matrixfile.close(); matrixfile.close();
// return to class // return to class
return sam; return sam;
} }
Sample readFas(char* itn){ Sample readFas(char* itn) {
int ntax, nchar, lnum; int ntax, nchar, lnum;
ifstream matrixfile; ifstream matrixfile;
matrixfile.open(itn); matrixfile.open(itn);
// check line number and taxa number // check line number and taxa number
ntax = 0; ntax = 0;
string temln; string temln;
for(lnum=0;getline(matrixfile,temln);lnum++){ for (lnum = 0; getline(matrixfile, temln); lnum++) {
if(temln[0]=='>'){ if (temln[0] == '>') {
ntax++; ntax++;
} }
} }
matrixfile.clear(); matrixfile.clear();
matrixfile.seekg(0); matrixfile.seekg(0);
// check the nchar // check the nchar
string *str_a = new string; string* str_a = new string;
string *str_b = new string; string* str_b = new string;
int r = lnum/ntax; int r = lnum / ntax;
for (int i=0; i<r;i++){ for (int i = 0; i < r; i++) {
getline(matrixfile, *str_a); getline(matrixfile, *str_a);
if(i>0){ if (i > 0) {
*str_b = *str_b + *str_a; *str_b = *str_b + *str_a;
} }
} }
nchar = (*str_b).length(); nchar = (*str_b).length();
@ -105,18 +105,18 @@ Sample readFas(char* itn){
// create class // create class
Sample sam(ntax, nchar); Sample sam(ntax, nchar);
// get class // get class
string *str_c = new string; string* str_c = new string;
for (int a=1, b=0;a<=lnum;a++){ for (int a = 1, b = 0; a <= lnum; a++) {
if(a%r==1){ if (a % r == 1) {
getline(matrixfile,sam.taxas[b]); getline(matrixfile, sam.taxas[b]);
sam.taxas[b].erase(0,1); sam.taxas[b].erase(0, 1);
} }
if(a%r>1){ if (a % r > 1) {
getline(matrixfile,*str_c); getline(matrixfile, *str_c);
sam.chars[b] = sam.chars[b] + *str_c; sam.chars[b] = sam.chars[b] + *str_c;
} }
if(a%r==0){ if (a % r == 0) {
getline(matrixfile,*str_c); getline(matrixfile, *str_c);
sam.chars[b] = sam.chars[b] + *str_c; sam.chars[b] = sam.chars[b] + *str_c;
b++; b++;
} }
@ -127,161 +127,170 @@ Sample readFas(char* itn){
return sam; return sam;
} }
Sample readTnt(char* itn){ Sample readTnt(char* itn) {
int ntax, nchar; int ntax, nchar;
ifstream matrixfile; ifstream matrixfile;
matrixfile.open(itn); matrixfile.open(itn);
// get nchar and ntax // get nchar and ntax
string stri, sntax, snchar; string stri, sntax, snchar;
for(int i=0;i<1;){ for (int i = 0; i < 1;) {
getline(matrixfile,stri); getline(matrixfile, stri);
istringstream istr(stri); istringstream istr(stri);
istr >> snchar; istr >> sntax; istr >> snchar;
if(isNum(sntax) && isNum(snchar)){ istr >> sntax;
ntax=stoi(sntax); if (isNum(sntax) && isNum(snchar)) {
nchar=stoi(snchar); ntax = stoi(sntax);
i++; nchar = stoi(snchar);
} i++;
}
} }
// create class // create class
Sample sam(ntax,nchar); Sample sam(ntax, nchar);
// get class // get class
int lennum; int lennum;
for(lennum=0;lennum<sam.ntax;lennum++){ for (lennum = 0; lennum < sam.ntax; lennum++) {
getline(matrixfile,stri); getline(matrixfile, stri);
istringstream istr(stri); istringstream istr(stri);
istr >> sam.taxas[lennum]; istr >> sam.chars[lennum]; istr >> sam.taxas[lennum];
istr >> sam.chars[lennum];
} }
matrixfile.close(); matrixfile.close();
return sam; return sam;
} }
bool isNum(string strnum) { bool isNum(string strnum) {
char* p; char* p;
strtol(strnum.c_str(), &p, 10); strtol(strnum.c_str(), &p, 10);
return *p == 0; return *p == 0;
} }
Sample readNex(char* itn){ Sample readNex(char* itn) {
int ntax, nchar; int ntax, nchar;
// open file // open file
ifstream matrixfile; ifstream matrixfile;
matrixfile.open(itn); matrixfile.open(itn);
// some tem // some tem
string snall, stri, str_a, str_b; string snall, stri, str_a, str_b;
bool found = false, found_ntax = false, found_nchar = false, found_equal = false; bool found = false, found_ntax = false, found_nchar = false,
found_equal = false;
char x = '='; char x = '=';
int lnum, eulnum; int lnum, eulnum;
// getline line by line // getline line by line
for(lnum=0;getline(matrixfile,snall);lnum++){ for (lnum = 0; getline(matrixfile, snall); lnum++) {
str_a = to_lower(snall); str_a = to_lower(snall);
str_b = add_space(x,str_a); str_b = add_space(x, str_a);
istringstream istr(str_b); istringstream istr(str_b);
// convert to words // convert to words
while(istr>> stri){ while (istr >> stri) {
if(stri=="dimensions"){ if (stri == "dimensions") {
found = true; found = true;
} else if(stri=="ntax"){ } else if (stri == "ntax") {
found_ntax = true; found_ntax = true;
} else if(stri=="nchar"){ } else if (stri == "nchar") {
found_nchar = true; found_nchar = true;
} else if(stri=="="){ } else if (stri == "=") {
found_equal = true; found_equal = true;
} else if (found_ntax&&found_equal){ } else if (found_ntax && found_equal) {
if(stri.back()==';'){ if (stri.back() == ';') {
stri.pop_back(); stri.pop_back();
found = false; found = false;
} }
ntax = stoi(stri); ntax = stoi(stri);
found_equal = false; found_equal = false;
found_ntax = false; found_ntax = false;
} else if (found_nchar&&found_equal){ } else if (found_nchar && found_equal) {
if(stri.back()==';'){ if (stri.back() == ';') {
stri.pop_back(); stri.pop_back();
found = false; found = false;
} }
nchar = stoi(stri); nchar = stoi(stri);
found_equal = false; found_equal = false;
found_nchar = false; found_nchar = false;
} else if (stri=="matrix"){ } else if (stri == "matrix") {
eulnum = lnum+1; eulnum = lnum + 1;
} }
} }
} }
// go back // go back
matrixfile.clear(); matrixfile.clear();
matrixfile.seekg(0); matrixfile.seekg(0);
// create class // create class
Sample sam(ntax,nchar); Sample sam(ntax, nchar);
// some temp, z is line number, l is the string arrary number // some temp, z is line number, l is the string arrary number
int z=0; int l=0; int z = 0;
int l = 0;
// read line by line // read line by line
while(getline(matrixfile,snall)){ while (getline(matrixfile, snall)) {
// convert to word // convert to word
istringstream istr(snall); istringstream istr(snall);
// limit the read line number // limit the read line number
if(z>(eulnum-1)&&z<(eulnum+sam.ntax)){ if (z > (eulnum - 1) && z < (eulnum + sam.ntax)) {
istr >> sam.taxas[l]; istr >> sam.taxas[l];
istr >> sam.chars[l]; istr >> sam.chars[l];
l++; l++;
} }
z++; z++;
} }
return sam; return sam;
} }
string add_space (char x, string str_old) { string add_space(char x, string str_old) {
int i; int i;
string str_new; string str_new;
for (i=0; i<str_old.length(); i++) { for (i = 0; i < str_old.length(); i++) {
if (str_old[i] != x) { if (str_old[i] != x) {
str_new=str_new+str_old[i]; str_new = str_new + str_old[i];
} else { } else {
str_new=str_new+" "+str_old[i]+" "; str_new = str_new + " " + str_old[i] + " ";
} }
} }
return str_new; return str_new;
} }
string to_lower(string stri){ string to_lower(string stri) {
transform(stri.begin(),stri.end(),stri.begin(),::tolower); transform(stri.begin(), stri.end(), stri.begin(), ::tolower);
return stri; return stri;
} }
void writeFas(class Sample sam, char* otn){ void writeFas(class Sample sam, char* otn) {
ofstream matrixfile(otn); ofstream matrixfile(otn);
for(int i=0;i<sam.ntax;i++){ for (int i = 0; i < sam.ntax; i++) {
matrixfile << ">" << sam.taxas[i] << endl; matrixfile << ">" << sam.taxas[i] << endl;
matrixfile << sam.chars[i] << endl; matrixfile << sam.chars[i] << endl;
} }
matrixfile.close(); matrixfile.close();
} }
void writePhy(class Sample sam, char* otn){ void writePhy(class Sample sam, char* otn) {
ofstream matrixfile(otn); ofstream matrixfile(otn);
matrixfile << sam.ntax << " " << sam.nchar << endl; matrixfile << sam.ntax << " " << sam.nchar << endl;
for(int i=0;i<sam.ntax;i++){ for (int i = 0; i < sam.ntax; i++) {
matrixfile << sam.taxas[i] << "\t" << sam.chars[i] << endl; matrixfile << sam.taxas[i] << "\t" << sam.chars[i] << endl;
} }
matrixfile.close(); matrixfile.close();
} }
void writeNex(class Sample sam, char* otn){ void writeNex(class Sample sam, char* otn) {
ofstream matrixfile(otn); ofstream matrixfile(otn);
string datatype; string datatype;
datatype = checktype(sam.chars[0]); datatype = checktype(sam.chars[0]);
matrixfile << "#NEXUS" << endl; matrixfile << "#NEXUS" << endl;
matrixfile << "Begin data;" << endl << "\tDimensions nchar=" << sam.nchar << " ntax=" << sam.ntax << ";" << endl << "\tFormat datatype=" << datatype << " missing=? gap=-;" << endl << "\tMatrix" << endl; matrixfile << "Begin data;" << endl
for(int i2=0;i2<sam.ntax;i2++){ << "\tDimensions nchar=" << sam.nchar << " ntax=" << sam.ntax
matrixfile << "\t\t" << sam.taxas[i2] << "\t" << sam.chars[i2] << endl; << ";" << endl
} << "\tFormat datatype=" << datatype << " missing=? gap=-;" << endl
matrixfile << "\t;" << endl << "End;" << endl; << "\tMatrix" << endl;
for (int i2 = 0; i2 < sam.ntax; i2++) {
matrixfile << "\t\t" << sam.taxas[i2] << "\t" << sam.chars[i2] << endl;
}
matrixfile << "\t;" << endl << "End;" << endl;
matrixfile.close(); matrixfile.close();
} }
string checktype(string str){ string checktype(string str) {
// some var // some var
float a, c, t, g, zero, one, two, dna, standard; float a, c, t, g, zero, one, two, dna, standard;
char ca='a', cc='c', ct='t', cg='g', czero='0', cone='1', ctwo='2'; char ca = 'a', cc = 'c', ct = 't', cg = 'g', czero = '0', cone = '1',
ctwo = '2';
string datatype; string datatype;
// count fre // count fre
a = countfre(str, ca); a = countfre(str, ca);
@ -292,131 +301,134 @@ string checktype(string str){
one = countfre(str, cone); one = countfre(str, cone);
two = countfre(str, ctwo); two = countfre(str, ctwo);
// summary dna or morphology // summary dna or morphology
dna = a+c+t+g; dna = a + c + t + g;
standard = zero+one+two; standard = zero + one + two;
// use percentage to test // use percentage to test
if((dna/str.length())>0.7){ if ((dna / str.length()) > 0.7) {
datatype = "dna"; datatype = "dna";
} else if ((standard/str.length())>0.7){ } else if ((standard / str.length()) > 0.7) {
datatype = "standard"; datatype = "standard";
} else { } else {
datatype = "protein"; datatype = "protein";
} }
return datatype; return datatype;
} }
int countfre(string str, char c){ int countfre(string str, char c) {
int num; int num;
str = to_lower(str); str = to_lower(str);
num = count(str.begin(),str.end(),c); num = count(str.begin(), str.end(), c);
return num; return num;
} }
void writeTnt(class Sample sam, char* otn){ void writeTnt(class Sample sam, char* otn) {
ofstream matrixfile(otn); ofstream matrixfile(otn);
matrixfile << "xread" << endl << "\' \'" << endl; matrixfile << "xread" << endl << "\' \'" << endl;
matrixfile << sam.nchar << " " << sam.ntax << endl; matrixfile << sam.nchar << " " << sam.ntax << endl;
for(int i=0;i<sam.ntax;i++){ for (int i = 0; i < sam.ntax; i++) {
matrixfile << sam.taxas[i] << "\t" << sam.chars[i] << endl; matrixfile << sam.taxas[i] << "\t" << sam.chars[i] << endl;
} }
matrixfile << "proc / ;" << endl; matrixfile << "proc / ;" << endl;
matrixfile.close(); matrixfile.close();
} }
Basic_arg procargs(int nargs, char** arg, char* itn, char* otn) {
Basic_arg procargs (int nargs, char ** arg, char* itn, char* otn){ int i, sta = 0, intype = 0, outype = 0;
int i, sta = 0, intype=0, outype=0;
string para, inputfile, outputfile; string para, inputfile, outputfile;
//no arg, show help // no arg, show help
if (nargs==1){ if (nargs == 1) {
show_help(0); show_help(0);
exit(0); exit(0);
sta=2; sta = 2;
} }
//recognize arg // recognize arg
for (i=1;i<nargs;i++){ for (i = 1; i < nargs; i++) {
//to string // to string
string para (arg[i]); string para(arg[i]);
if ( para =="-h"| para=="--help" ) { if (para == "-h" | para == "--help") {
show_help(1); show_help(1);
sta=2; sta = 2;
} } else if (para == "-i" | para == "--input") {
else if ( para =="-i"| para=="--input"){ i++;
i++; itn = arg[i];
itn=arg[i]; string inputfile(arg[i]);
string inputfile (arg[i]); intype = checkextension(inputfile);
intype = checkextension(inputfile); sta++;
sta++; } else if (para == "-o" | para == "--output") {
} i++;
else if ( para =="-o"| para=="--output"){ otn = arg[i];
i++; string outputfile(arg[i]);
otn=arg[i]; outype = checkextension(outputfile);
string outputfile (arg[i]); sta++;
outype = checkextension(outputfile);
sta++;
} else { } else {
cout << "MiMi\tUnknown arguments, please use -h to check" << endl; cout << "MiMi\tUnknown arguments, please use -h to check" << endl;
exit(0); exit(0);
} }
} }
if(sta!=2){ if (sta != 2) {
cout << "MiMi\tInput and Output can't be empty" << endl; cout << "MiMi\tInput and Output can't be empty" << endl;
exit(0); exit(0);
} }
Basic_arg arguvar(intype,outype,itn,otn); Basic_arg arguvar(intype, outype, itn, otn);
return arguvar; return arguvar;
} }
int checkextension(string str){ int checkextension(string str) {
int loc, type; int loc, type;
string extension; string extension;
loc = str.rfind('.'); loc = str.rfind('.');
if(loc){ if (loc) {
extension = str.substr(loc+1); extension = str.substr(loc + 1);
} else {
cout << "MiMi\tPlease sepecifc the extension name" << endl;
exit(0);
}
extension = to_lower(extension);
if(extension=="fas"|extension=="fasta"){
type = 1;
} else if (extension=="nex"|extension=="nexus"){
type = 2;
} else if (extension=="phy"|extension=="phylip"){
type = 3;
} else if (extension=="tnt"|extension=="ss"){
type = 4;
} else {
cout << "MiMi\tUnknown format" << endl;
exit(0);
}
return type;
}
void show_help (int help_num){
if (help_num == 0){
cout << "MiMi, GPL, Guoyi Zhang, 2023.\nPlease use -h to see more help" << endl;
} else { } else {
cout << "\n l、 \t. . . .\n(゚、 。 \t|\\/|*|\\/|*\n l ~ヽ \t| ||| ||\n じしf_,)\t| ||| ||\n" << endl; cout << "MiMi\tPlease sepecifc the extension name" << endl;
cout << "Morphology into Molecules into\n" << "GPL\tGuoyi\tZhang,\t2023\n" << endl; exit(0);
cout << "-h\t--help;\n-i\t--input\t\t${filename};\n-o\t--output\t${filename};\n" << endl; }
cout << "Accepted format:\nfas\tfasta;\nnex\tnexus\nphy\tphylip\ntnt\tss" << endl; extension = to_lower(extension);
if (extension == "fas" | extension == "fasta") {
type = 1;
} else if (extension == "nex" | extension == "nexus") {
type = 2;
} else if (extension == "phy" | extension == "phylip") {
type = 3;
} else if (extension == "tnt" | extension == "ss") {
type = 4;
} else {
cout << "MiMi\tUnknown format" << endl;
exit(0);
}
return type;
}
void show_help(int help_num) {
if (help_num == 0) {
cout << "MiMi, GPL, Guoyi Zhang, 2023.\nPlease use -h to see more help"
<< endl;
} else {
cout << "\n l、 \t. . . .\n(゚、 。 \t|\\/|*|\\/|*\n l ~ヽ "
" \t| ||| ||\n じしf_,)\t| ||| ||\n"
<< endl;
cout << "Morphology into Molecules into\n"
<< "GPL;\tGuoyi Zhang;\t2023\n"
<< endl;
cout << "-h\t--help;\n-i\t--input\t\t${filename};\n-o\t--output\t${"
"filename};\n"
<< endl;
cout
<< "Accepted formats:\nfas\tfasta;\nnex\tnexus;\nphy\tphylip;\ntnt\tss;"
<< endl;
} }
} }
Sample read_input (char* itn, int intype){ Sample read_input(char* itn, int intype) {
int ntax, nchar; int ntax, nchar;
Sample sam(ntax,nchar); Sample sam(ntax, nchar);
ifstream matrixfile; ifstream matrixfile;
matrixfile.open(itn); matrixfile.open(itn);
if (matrixfile.is_open()){ if (matrixfile.is_open()) {
if (intype==1) sam = readFas(itn); if (intype == 1) sam = readFas(itn);
if (intype==2) sam = readNex(itn); if (intype == 2) sam = readNex(itn);
if (intype==3) sam = readPhy(itn); if (intype == 3) sam = readPhy(itn);
if (intype==4) sam = readTnt(itn); if (intype == 4) sam = readTnt(itn);
} else { } else {
cout << "MiMi\tInput file can't be open" << endl; cout << "MiMi\tInput file can't be open" << endl;
exit(0); exit(0);
@ -424,48 +436,47 @@ Sample read_input (char* itn, int intype){
return sam; return sam;
} }
void write_output (class Sample sam, char* otn, int outype){ void write_output(class Sample sam, char* otn, int outype) {
ofstream matrixfile(otn); ofstream matrixfile(otn);
if (matrixfile.is_open()) { if (matrixfile.is_open()) {
if (outype==1) writeFas(sam,otn); if (outype == 1) writeFas(sam, otn);
if (outype==2) writeNex(sam,otn); if (outype == 2) writeNex(sam, otn);
if (outype==3) writePhy(sam,otn); if (outype == 3) writePhy(sam, otn);
if (outype==4) writeTnt(sam,otn); if (outype == 4) writeTnt(sam, otn);
} else { } else {
cout << "MiMi\tOutput file can't be open" << endl; cout << "MiMi\tOutput file can't be open" << endl;
exit(0); exit(0);
} }
} }
bool checkalign(class Sample sam){ bool checkalign(class Sample sam) {
int a=0, b=0, x=0; int a = 0, b = 0, x = 0;
a = sam.nchar; a = sam.nchar;
bool aligned = true; bool aligned = true;
for(int i=0;i<sam.ntax;i++){ for (int i = 0; i < sam.ntax; i++) {
b=sam.chars[i].length(); b = sam.chars[i].length();
if(a==b){ if (a == b) {
x++; x++;
} }
} }
if (x!=sam.ntax){ if (x != sam.ntax) {
aligned = false; aligned = false;
} }
return aligned; return aligned;
} }
int main(int argc, char** argv) {
int main(int argc, char **argv){
char *itn, *otn; char *itn, *otn;
Basic_arg arguvar = procargs (argc, argv, itn, otn); Basic_arg arguvar = procargs(argc, argv, itn, otn);
if(arguvar.intype!=0&&arguvar.outype!=0){ if (arguvar.intype != 0 && arguvar.outype != 0) {
Sample sam = read_input(arguvar.itn,arguvar.intype); Sample sam = read_input(arguvar.itn, arguvar.intype);
cout << "MiMi:\tInput\tfinished" << endl; cout << "MiMi:\tInput\tfinished" << endl;
if(!checkalign(sam)){ if (!checkalign(sam)) {
cout << "MiMi:\tInput file should be aligned" << endl; cout << "MiMi:\tInput file should be aligned" << endl;
exit(0); exit(0);
} }
write_output(sam,arguvar.otn,arguvar.outype); write_output(sam, arguvar.otn, arguvar.outype);
cout << "MiMi:\tOutput\tfinished" << endl; cout << "MiMi:\tOutput\tfinished" << endl;
} }
return 0; return 0;
} }