# hw9-3 {%hackmd BJrTq20hE %} ```cpp= #include <iostream> #include <fstream> #include <vector> using namespace::std; // reads in a C++ program from a cpp file, and put it to the vector program void load( vector< char * > &program ); // deletes the comment beginning with "//" from sourceLine if any void delComment( char sourceLine[] ); // deletes all string constants from sourceLine void delStrConsts( char sourceLine[] ); // deletes all character constants from sourceLine void delCharConsts( char sourceLine[] ); // extracts all identifiers from sourceLine, and put them into the vector identifiers void extractIdentifiers( char sourceLine[], vector< char * > &identifiers ); // stores all non-keyword strings in the vector identifiers into a text file void store( vector< char * > &identifiers ); // returns true if and only if str is a C++ keyword bool keyword( char str[] ); // returns true if and only if identifiers[ pos ] belongs to identifiers[ 0 .. pos-1 ] bool duplicate( vector< char * > &identifiers, int pos ); const char keywords[][ 20 ] = { "auto", "break", "case", "char", "const", "continue", "default", "define","do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", "bool", "catch", "class", "const_cast", "delete", "dynamic_cast", "explicit", "false", "friend", "inline", "mutable", "namespace", "new", "operator", "private", "protected", "public", "reinterpret_cast", "static_cast", "template", "this", "throw", "true", "try", "typeid", "typename", "using", "virtual", "include" }; int main() { vector< char * > program; //看成vector(陣列)的每一個元素都是字串,而字串的組成是由char指標往外指出來的 (二維) //***********************用push_back來新增一格(一行程式碼) // reads in a C++ program from a cpp file, and put it to the vector program load( program ); vector< char * > identifiers; for( size_t i = 0; i < program.size(); i++ ) { delComment( program[ i ] ); // deletes the comment beginning with "//" from program[ i ] delStrConsts( program[ i ] ); // deletes all string constants from program[ i ] delCharConsts( program[ i ] ); // deletes all character constants from program[ i ] if( strcmp( program[ i ], "" ) != 0 ) extractIdentifiers( program[ i ], identifiers ); // extracts all identifiers from program[ i ], and put them into the vector identifiers } // stores all non-keyword strings in the vector identifiers into a text file store( identifiers ); system( "pause" ); } void load( vector< char * > &program ) { //////////////////// //開檔: //ifstream inFile("C:\\Users\\mcpe9\\Desktop\\test1.cpp", ios::in); ifstream inFile("test2.cpp", ios::in); if (!inFile) { cerr << "File could not be opened" << endl; system("pause"); exit(1); } else { //讀資料: char* temp = new char[100](); while (inFile.getline(temp, 100)) { program.push_back(temp); //丟入temp存放的address,讓program也指向跟temp一樣的空間 temp = new char[100](); //指到新的空間 } //刪最後一個空行的空間,前面累積的空間到extractIdentifiers再刪掉 delete[] temp; } //***關檔*** inFile.close(); //////////////////// } void delComment( char sourceLine[] ) { size_t length = strlen( sourceLine ); if( length > 1 ) for( size_t i = 0; i < length - 1; i++ ) if( sourceLine[ i ] == '/' && sourceLine[ i + 1 ] == '/' ) { sourceLine[ i ] = '\0'; return; } } void delStrConsts( char sourceLine[] ) { //////////////////// size_t length = strlen(sourceLine); if (length > 1) { for (size_t i = 0; i < length - 1; i++) { if (sourceLine[i] == '"') { sourceLine[i] = ' '; i++; while (true) { //發生 ex1: "Enter the string \"eat here\":" // ex2: "\"\"" if (sourceLine[i] == '\\' && sourceLine[i + 1] == '"') { sourceLine[i] = ' '; sourceLine[i + 1] = ' '; i += 2; //***i+2*** } else if (sourceLine[i] == '"') { sourceLine[i] = ' '; i++; break; } else { sourceLine[i] = ' '; i++; } } } } } //////////////////// } void delCharConsts( char sourceLine[] ) { //////////////////// size_t length = strlen(sourceLine); //刪掉字元常數 ex: 'a', '\n' if (length > 1) { for (size_t i = 0; i < length - 1; i++) { if (sourceLine[i] == '\'') { sourceLine[i] = ' '; i++; while (true) { //發生 ex: s1[ 0 ] << '\'' << s1[ 1 ] => \' if (sourceLine[i] == '\\' && sourceLine[i + 1] == '\'') { sourceLine[i] = ' '; //刪掉 '\' sourceLine[i + 1] = ' '; //刪掉 '"' i += 2; } else if (sourceLine[i] == '\'') { sourceLine[i] = ' '; break; } else { sourceLine[i] = ' '; i++; } } } } } //////////////////// } void extractIdentifiers( char sourceLine[], vector< char * > &identifiers ) { //////////////////////////////////////// size_t length = strlen(sourceLine); //刪掉符號(用ASCII判斷): if (length > 0) { for (size_t i = 0; i < length; i++) { //非數字and非英文字母 if ( !(sourceLine[i] >= '0' && sourceLine[i] <= '9') && //*** '0' ~ 9 *** !(sourceLine[i] >= 'a' && sourceLine[i] <= 'z') && !(sourceLine[i] >= 'A' && sourceLine[i] <= 'Z') && //***英文大小寫*** sourceLine[i] != '_' //***為底線時不刪除*** ) { sourceLine[i] = ' '; } } } //不為keyword則丟入identifiers空間 if (length > 1) { for (int i = 0; i < length; i++) //檢查一整行字元 i < 100 { //有東西時進入 ex:cout int if (sourceLine[i] != ' ' && sourceLine[i] != '\0') //*****每跑一次temp這個pointer會不見,所以主要透過temp把address傳給identifiers,讓它指到空間*** { //所以主要透過temp把address傳給identifiers,讓它指到空間****** //***要寫在裡面***,以免出現空的空間,導致不會讓identifiers指向他 char* temp = new char[32](); //裡面全塞'\0'(空字元or結束字元),' '(空白字元) int i_temp = 0; //temp存一行的其中一個identifier while (true) { temp[i_temp] = sourceLine[i]; i_temp++; i++; if (sourceLine[i] == ' ') //下一項 { break; } } //把剛存的temp丟入identifier if ((!keyword(temp)) && (!(temp[0] >= '0' && temp[0] <= '9'))) //判斷不能為keyword,第一個字不能為數字 { identifiers.push_back(temp); //***不用補'\0'*** } else //表示identifiers不會指向temp,到method store時會沒辦法刪掉 { delete[] temp; } } } } //from load: delete[] sourceLine; //***刪掉Load的temp*** //***到了store再刪掉temp空間*** //////////////////////////////////////// } void store( vector< char * > &identifiers ) { //////////////////// //寫檔: //ofstream outFile("C:\\Users\\mcpe9\\Desktop\\identifiers.txt", ios::out); ofstream outFile("identifiers.txt", ios::out); for (int i = 0; i < identifiers.size(); i++) //***VectorName.size()*** { char temp[32]{}; if (!duplicate(identifiers, i)) //重複回傳true { outFile << identifiers[i]; outFile << endl; } } //***刪空間*** //from extractIdentifiers: for (int i = 0; i < identifiers.size(); i++) { delete[] identifiers[i]; } //***關檔*** outFile.close(); //////////////////// } bool keyword( char str[] ) { size_t numKeywords = sizeof( keywords ) / 20; for( size_t i = 0; i < numKeywords; i++ ) if( strcmp( keywords[ i ], str ) == 0 ) return true; return false; } bool duplicate( vector< char * > &identifiers, int pos ) { for( int i = 0; i < pos; i++ ) if( strcmp( identifiers[ i ], identifiers[ pos ] ) == 0 ) return true; return false; } ```