2010-07-21 49 views
2

)我的問題是我正在嘗試爲ascii文本文件編寫一個非常基本的詞法分析器,到目前爲止,它讀取和比較到我的令牌列表正確,但是我無法抓住沒有空格或按下輸入的最後一個令牌。我已經嘗試使用分隔符^ Z ASCII 26作爲另一個選擇之前,比較字符串與我的令牌列表,這失敗了。我也嘗試將f-> eof()檢查移動到比較位置下面,看看它是否會阻止它然後檢查eof標誌。我沒有運氣。是否有人可能啓發我?代碼是低於讀取方法m_TokenList只是一個字符串類型的向量當使用C++ get讀取文件時,行尾字符是什麼(char & c);?

void CelestialAnalyzer::ReadInTokens(ifstream *f){ 
vector<string> statement; 
vector<string> tokens; 
string token; 
char c; 
do{ 
f->get(c); // Read in each character 
if(f->eof()) 
break; 

if(c == '\n' || c == ' ' || c == '^Z' || c == '\r'){ // 26 ASCII ^Z (end of file marker) 
for(unsigned int i=0; i<m_TokenList.size(); i++){ 
    if(!token.compare(m_TokenList[i])){ 
    tokens.push_back(token); 
    token.clear(); 
} 
} 
} else { 
token.push_back(c); // Add it to the token array 
} 
} while (true); 





f->close(); 

for(unsigned int i=0; i<tokens.size(); i++){ 
cout << "Found Token: " << tokens[i].c_str() << endl; 
} 

}

的m_TokenList被初始化爲

CelestialAnalyzer::CelestialAnalyzer(){ 
m_TokenList.push_back("KEY"); // Prints data 
m_TokenList.push_back("GETINPUT"); // Grabs user data 
m_TokenList.push_back("+"); // Addition/Concation 
m_TokenList.push_back("-"); // Subtraction 
m_TokenList.push_back("=="); // Equator 
m_TokenList.push_back("="); // Assignment 
m_TokenList.push_back(";"); // End statement 
m_TokenList.push_back(" "); // Blank 
m_TokenList.push_back("{"); // Open Grouping 
m_TokenList.push_back("}"); // Close Grouping 
m_TokenList.push_back("("); // Parameter opening 
m_TokenList.push_back(")"); // Parameter closing 
for(unsigned int i=48; i<=57; i++){ 
string s; s.push_back((char)i); 
m_TokenList.push_back(s); s.clear(); 
} 
} 

一種用於讀取測試文件這個簡單的例子。 1 + 2 = KEY

它將註冊除'KEY'之外的所有內容,除非後面有空格或換行符。

+0

對「^ Z是文件結尾」的評論完全錯誤。這是Windows用來表示終端輸入結束的混亂,程序將不會看到「字符標記輸入結束」(實際上,^ Z是完全有效的字符)。無論數據來自何處,操作系統都會將其結尾標記給調用者,因爲文件的長度已達到或用戶這麼說。 – vonbrand 2013-01-30 12:06:05

回答

2

你爲什麼不直接刪除:

if(f->eof()) break;

,並使用

if(f->eof() || c == '\n' || c == ' ' || c == '^Z' || c == '\r'){

再破後來呢?這樣,當你擊中EOF時,你會添加你剩下的任何剩餘的標記。

或者,您可以在跳出循環後檢查標記是否非空,並在該情況下添加它。

+0

固定它與 bool eof = false; \t do { \t \t f-> get(c); \t \t \t //讀取中的每個字符 \t \t如果(C == '\ n' \t \t \t ||Ç== '' \t \t \t ||Ç== '^ Z' \t \t \t ||ç== '\ r' \t \t \t || F-> EOF()){// \t 26 ASCII^Z(文件標記) \t \t \t爲結束(無符號整型I = 0; I < m_TokenList。尺寸();我++){ \t \t \t \t如果){ \t \t \t \t \t tokens.push_back(令牌)(token.compare(m_TokenList [I]!); \t \t \t \t \t token.clear(); \t \t \t \t} \t \t \t} \t \t}否則{ \t \t \t token.push_back(C); \t //它添加到令牌陣列 \t \t} \t \t如果(F-> EOF()) \t \t \t EOF = TRUE; (!eof); – 2010-07-21 01:59:43

0

雙'新線'怎麼樣?據我所知,在幾個消息協議方面關於\ r \ n \ r \ n與消息的結尾。我認爲這很合理。 :)

+0

沒有運氣,只是嘗試'\ r \ n'和'\ r \ n \ r \ n'。無論哪種方式,我只是比較一個字符在一次。它只會拿起第一個正確的? – 2010-07-21 01:43:24

相關問題