Какой символ конца строки при чтении файла в C ++ get (char & c) ;? - PullRequest
2 голосов
/ 21 июля 2010

Моя проблема в том, что я пытаюсь сделать первую попытку написать очень простой лексический анализатор для текстовых файлов ascii. до сих пор он правильно читает и сравнивает мой список токенов, однако я не могу получить окончательный токен без пробела или нажатия клавиши ввода. Я попытался использовать разделитель ^ Z ASCII 26 в качестве другого выбора, прежде чем сравнивать строку с моим списком токенов. Это не сработало. Я также попытался переместить проверку f-> eof () ниже места сравнения, чтобы посмотреть, не поймет ли она, а затем проверить флаг eof. Мне не повезло. кто-нибудь может просветить меня? Код ниже для метода чтения. m_TokenList - это просто вектор типа string.

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», если после него не будет пробела или новой строки.

Ответы [ 2 ]

2 голосов
/ 21 июля 2010

Почему бы вам просто не удалить:

if(f->eof()) break;

и используйте

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

потом сломаешься? Таким образом, когда вы нажимаете EOF, вы добавляете оставшийся токен.

Кроме того, вы можете просто проверить, не является ли токен пустым после выхода из цикла, и добавить его в этом случае.

0 голосов
/ 21 июля 2010

А как насчет двойной «новой строки»? Как я знаю, в нескольких мессенджерах протокол относят \ r \ n \ r \ n к концу сообщения. Я думаю, что это довольно разумно. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...