提问人:Redstonerayy 提问时间:11/18/2021 最后编辑:Redstonerayy 更新时间:11/18/2021 访问量:142
循环外的语句重复 c++
Statement outside of loop gets repeated c++
问:
我尝试从用户的输入中读取令牌,就像编译器一样。 标记化工作正常,但是在输出所有令牌时,我想在它们全部发出后换行。
这是我的代码:
#include <iostream>
#include <map>
#include <vector>
//import for using std::getline()
#include <string>
//DIGITs
const std::string DIGITS = "0123456789";
const std::string WHITESPACE = " \t\n\r";
//TOKENS
const std::string TT_INT = "INT";
const std::string TT_FLOAT = "FLOAT";
const std::string TT_PLUS = "PLUS";
const std::string TT_MINUS = "MINUS";
const std::string TT_MUL = "MUL";
const std::string TT_DIV = "DIV";
const std::string TT_LPAREN = "LPAREN";
const std::string TT_RPAREN = "RPAREN";
const std::string TT_INVALID_NUMBER = "INVALID_NUMBER_LITERAL";
class Token{
public:
std::string type;
std::string value;
void repr(){
std::cout << type << ":" << "value" << "\n";
}
};
class Lexer{
public:
std::string text;
int position = -1;
std::string current_char;
void advance(){
this->position += 1;
this->current_char = this->text[this->position];
}
void make_digit(std::string *type, std::string *value){
//if its number or floating point
std::string digit = "";
int is_float = 0;
while(DIGITS.find(this->current_char) != std::string::npos || this->current_char == "."){
digit += this->current_char;
if(this->current_char == "."){
is_float += 1;
}
this->advance();
}
*value = digit;
if(is_float == 0){
*type = TT_INT;
} else if((0 < is_float) && (is_float < 2)){
*type = TT_FLOAT;
} else {
*type = TT_INVALID_NUMBER;
}
}
std::vector<std::string> make_tokens(){
std::vector<std::string> tokens;
this->advance();
while (!(this->text.length() <= this->position))
{
if(WHITESPACE.find(this->current_char) != std::string::npos){
//dont add a token
this->advance();
} else if(DIGITS.find(this->current_char) != std::string::npos){
std::string type;
std::string value;
this->make_digit(&type, &value);
tokens.push_back(type);
tokens.push_back(value);
} else if(this->current_char == "+"){
tokens.push_back(TT_PLUS);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "-"){
tokens.push_back(TT_MINUS);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "*"){
tokens.push_back(TT_MUL);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "/"){
tokens.push_back(TT_DIV);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "("){
tokens.push_back(TT_LPAREN);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == ")"){
tokens.push_back(TT_RPAREN);
tokens.push_back(this->current_char);
this->advance();
} else {
//nothing
this->advance();
}
}
return tokens;
}
};
int main(){
//previous: true
while(std::getline(std::cin, input)){
std::string input;
//previous: std::cin >> input;
//fix
std::getline(std::cin, input);
Lexer mylexer;
mylexer.text = input;
int x = 0;
std::vector<std::string> output = mylexer.make_tokens();
for (int i = 0; i < output.size(); i += 2){
std::cout << output.at(i) << ":" << output.at(i + 1) << std::endl;
}
std::cout << "\n";
}
};
输入 1 + 2 时
我的期望
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
我得到了什么
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
当删除末尾的换行符时,我得到了这个,但是当输入第二个输入行时,它全部在一起,没有空行,这不是我想要的
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
但我希望它看起来像这样
1 + 2
INT:1
PLUS:+
INT:2
3 + 4
INT:3
PLUS:+
INT:4
谁能解释一下这种奇怪的行为是什么? 我错过了什么吗?请注意,我没有太多的C++经验。 我在Windows上使用clang-cl.exe进行编译。我也想知道使用 MSYS2 g++ 编译时throw_bad_array_new_lengthv错误是什么意思.exe
答:
输出中出现额外换行符的原因是,您正在使用 .operator>>
input
operator>>
一次只能阅读 1 个单词。当遇到空格时,它会停止读取。
因此,当您输入作为输入时,您最终只使用第一个单词作为 ,然后循环打印出来,然后换行符,然后在循环退出后打印出另一个换行符。然后,您阅读下一个单词,对其进行标记化,然后打印出来,然后是 2 个换行符。然后你读下一个单词,标记它,并打印出来,然后是 2 个换行符。1 + 2
make_tokens()
1
mylexer.text
INT:1
+
PLUS:+
2
INT:2
请改用。然后,您将在一次调用中标记整个输入,然后您将打印出您期望的输出类型 - 所有 3 个标记,它们之间有 1 个换行符,然后在结束后再换行 1 个换行符。std::getline(std::cin, input);
1 + 2
make_tokens()
顺便说一句:你不应该使用循环,特别是因为你忽略了阅读是否成功。您正在导致一个无限循环,可能会使代码崩溃。while(true)
std::cin
当没有更多输入要读取时,您应该使用 的错误状态来停止循环,例如:std::cin
std::string input;
while (std::cin >> input){
// use input as needed...
}
或者,在以下情况下:std::getline()
std::string input;
while (std::getline(std::cin, input)){
// use input as needed...
}
评论
std::cin
std::cin
operator>>
istream
std::cin
std::getline()
std::cin
std::cin
std::istream
operator>>
std::getline()
std::istream
std::ifstream
std::istringstream
std::istream
std::stream_buf
std::cin
std::stream_buf
STDIN
operator>>/getline <- cin <- stream_buf <- STDIN
std::cout
STDOUT
std::cerr
STDERR
评论
std::endl
\n
\n