Problém se zadáváním uživatelského vstupu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Problém se zadáváním uživatelského vstupu – C / C++ – Fórum – Programujte.comProblém se zadáváním uživatelského vstupu – C / C++ – Fórum – Programujte.com

 

DMS
~ Anonymní uživatel
1 příspěvek
15. 2. 2014   #1
-
0
-

Ahoj, někde jsem našel zdroják k programu, který upravuje a řeší lineární rovnice. Problém mám s uživatelským vstupem. Takto program funguje bezvadně, ale vůbec mě nenapadá jak bych mohl tento řádek reprezentovat uživatelským vstupem: 

5 + x == 10/2*(8-3);
#include <iostream>

struct VAR{
	float i;
};

struct LINE{//k*x+a
	float a, k;
	VAR* x;

	LINE(){}
	LINE(int a) : a(a), k(0), x(0) {}
	LINE(VAR& v) : a(0), k(1), x(&v) {}
};

LINE operator + (LINE A, LINE B){//assumes that A.x == 0 or B.x == 0 or A.x == B.x
	LINE R;
	R.a = A.a + B.a;
	R.k = A.k + B.k;
	if(A.x) R.x = A.x;
	else R.x = B.x;
	return R;
}

LINE operator - (LINE A, LINE B){//same as +
	LINE R;
	R.a = A.a - B.a;
	R.k = A.k - B.k;
	if(A.x) R.x = A.x;
	else R.x = B.x;
	return R;
}

LINE operator * (LINE A, LINE B){//assumes that A.x == 0 or B.x == 0
	LINE R;
	R.a = A.a * B.a;
	R.k = A.k * B.a + B.k * A.a;
	if(A.x) R.x = A.x;
	else R.x = B.x;
	return R;
}

LINE operator / (LINE A, LINE B){//assumes that B.x == 0
	LINE R;
	R.a = A.a / B.a;
	R.k = A.k / B.a;
	R.x = A.x;
	return R;
}

void operator == (LINE A, LINE B){
	LINE C = A - B;
	C.x->i = -C.a/C.k;
}

int main(){
	VAR x;
	5 + x == 10/2*(8-3);

	std::cout << "x = " << x.i;
	std::cin.get();

	return 0;
}
Nahlásit jako SPAM
IP: 88.101.39.–
KIIV
~ Moderátor
+43
God of flame
15. 2. 2014   #2
-
0
-

bez vhodneho parseru docela tezko...  leda mit format  ax+b = 0 a zadat a a b

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
15. 2. 2014   #3
-
0
-

#1 DMS
Mozes skusit takyto parser:

#include <vector>
#include <iostream>
#include <stdexcept>
#include <cassert>

enum class Key{
	Number,
	
	OpAdd,
	OpSub,
	OpMul,
	OpDiv,
	OpBracketL,
	OpBracketR,
		
	Eof	
};

struct Token{
	Key key;
	std::string val;
	
	Token(Key key):key(key){}
	Token(Key key, const std::string& val):key(key), val(val){}
	Token(Key key, std::string&& val):key(key), val(std::move(val)){}
};

std::vector<Token> scan(std::istream& in){
	std::vector<Token> tokens;
	
	while(1){
		int i = in.get();
		DENGO:
		switch(i){
			case ' ':
			case '\t':
				continue;
			case '\n':
				tokens.emplace_back(Key::Eof);
				return tokens;	
			case '+':
				tokens.emplace_back(Key::OpAdd);
				continue;
			case '-':
				tokens.emplace_back(Key::OpSub);
				continue;
			case '*':
				tokens.emplace_back(Key::OpMul);
				continue;
			case '/':
				tokens.emplace_back(Key::OpDiv);
				continue;
			case '(':
				tokens.emplace_back(Key::OpBracketL);
				continue;
			case ')':
				tokens.emplace_back(Key::OpBracketR);
				continue;	
				
			case '0':case '1':case '2':case '3':case '4':
			case '5':case '6':case '7':case '8':case '9':	{
				std::string str;
				str += (char)i;
				
				while(1) switch((i = in.get())){
					case '0':case '1':case '2':case '3':case '4':
					case '5':case '6':case '7':case '8':case '9':
						str += (char)i;
						continue;
						
					case '\n':
						tokens.emplace_back(Key::Number, str);
						tokens.emplace_back(Key::Eof);
						return tokens;
						
					default:
						tokens.emplace_back(Key::Number, str);
						goto DENGO;
						
					break;
				};
				
				continue;	
			}		
		}
		
		throw std::logic_error("Neznamy symbol");
	}
	assert(0);
}

double parseValue(std::vector<Token>::const_iterator& tok);
double parseAdd(std::vector<Token>::const_iterator& tok);
double parseMul(std::vector<Token>::const_iterator& tok);

double parseValue(std::vector<Token>::const_iterator& tok){
	switch(tok->key){
		case Key::Number:{
			double d = std::stod(tok->val);
			++tok;
			return d;
		}
		case Key::OpBracketL:{
			double d = parseAdd(++tok);
			if(tok->key != Key::OpBracketR)throw std::logic_error("chyba znak ')'");
			return d;
		}
		
		default:
			throw std::logic_error("Neznama hodnota");
	}
	assert(0);
}

double parseMul(std::vector<Token>::const_iterator& tok){
	double left = parseValue(tok);
	
	while(1) switch(tok->key){
		case Key::OpMul:
			left *= parseValue(++tok);
			break;
			
		case Key::OpDiv:
			left /= parseValue(++tok);
			break;
			
		default:
			return left;
	}
	assert(0);
}

double parseAdd(std::vector<Token>::const_iterator& tok){
	double left = parseValue(tok);
	
	while(1) switch(tok->key){
		case Key::OpAdd:
			left += parseMul(++tok);
			break;
			
		case Key::OpSub:
			left -= parseMul(++tok);
			break;
			
		default:
			return left;
	}
	assert(0);
}

double parse(const std::vector<Token>& tokens){
	//for(auto& tok : tokens)std::cout << "(" << tok.key << "\t:\t" << tok.val << ")\n";
	auto tok = tokens.begin();
	double d = parseAdd(tok);
	if(tok->key == Key::Eof)return d;
	throw std::logic_error("PARSE ERROR");
}

int main(){
	using namespace std;
	while(1){
		std::cout << "= " << parse(scan(std::cin)) << ";\n\n";
	}
	return 0;
}

Tento konkretny parser vie spracovat matematicky vyraz obsahujuci operatory + - * / a zatvorky () .

Vyraz musy byt ukonceny znakom '\n'.

Operatory * a / maju vecsiu prioritu ako + a -.

Po urcitych upravach by sa tento parser dal pouzit aj pre tvoj pripad. 

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
vitamin+8
Grafoman
16. 2. 2014   #4
-
0
-
Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 53 hostů

Podobná vlákna

Problém se čtením vstupu... — založil eidam1995

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý