PDA

Показать полную графическую версию : [решено] Строка после ввода vs посимвольно заданая


Prof
10-04-2014, 18:51
Доброго времени суток, ув. форумчане! Работаю с обратной польской (постфиксной) записью. Обрабатывается строка следующим образом:

if (strcmp(line, "+") == 0) {
onAdd();
}
else if (strcmp(line, "-") == 0) {
onSub();
}
else if (strcmp(line, "*") == 0) {
onMul();
}
else if (strcmp(line, "/") == 0) {
onDiv();
}
else if (strcmp(line, "s") == 0) {
onSin();
}
...

Если вводить с помощью cin или scanf, то всё работает нормально, а если та же строка записывается посимвольно, то алгоритм циклится на первом элементе (соответсвенно забивает стек). В чём разница между двумя видами ввода?

lxa85
11-04-2014, 08:55
Prof, а покажи "обвязку" посимвольного ввода?
Т.е. как получается переменная line?
Есть предположение, что при вводе передается символ окончания строки. Т.е. каждый введенный символ воспринимается как отдельная строка. Надо больше кода! :)

Prof
12-04-2014, 18:58
Перевод формулы в опз:
note - ввод с клавиатуры

class stack
{
int top;
char body[256];
public:
stack(){ top = 0; }
bool empty(){ return top == 0; }
char get_top_element(){ return body[top]; }
int top_prior(){ return prior(body[top]); }
void push(char x)
{
top++;
body[top] = x;
}
char pop()
{
top--;
return body[top + 1];
}
};
--------------------------------
stack s;
for (i = 0; i<strlen(note); i++)
{
if (note[i] == '(')
s.push(note[i]);
else if ((note[i] == '+') || (note[i] == '-') || (note[i] == '/') || (note[i] == '*'))
{
while ((!s.empty()) && (s.top_prior()>prior(note[i])))
{
p++;
line[p] = s.pop();
space_add();
}
s.push(note[i]);
}
else if ((note[i] == 's') || (note[i] == 'c') || (note[i] == 'l') || (note[i] == 'e'))
{
if (note[i + 1] == 'q'){
s.push(note[i + 1]);
i = i + 3;
}
else {
s.push(note[i]);
i = i + 2;
}
}
else if (note[i] == ')')
{
while ((!s.empty()) && (s.get_top_element() != '('))
{
p++;
line[p] = s.pop();
space_add();
}
s.pop();
if (s.top_prior() == -1){
p++;
line[p] = s.pop();
space_add();
}
}
else
{
if (isdigit(note[i]))
{
while (isdigit(note[i]))
{
p++;
line[p] = note[i];
i++;
}
i--;
}
else
{
p++;
line[p] = note[i];
}
space_add();
}
}
while (!s.empty())
{
p++;
line[p] = s.pop();
space_add();
}
p = p + 1;
line[p] = '=';
}

Prof
12-04-2014, 23:05
Разобрался: я совсем забыл про такую чудесную штуку, как "\0" . Когда вводим строку типа "1 1 + =" методом cin >> line в цикле (как в моём случае):

while (ccl)
{
cin >> line;
...

то элементы считываются по одному, то есть строка обретает следующий вид:
1-й проход: 1 \0
2-й проход: 1 \0
3-й проход: + \0
4-й проход: = \0
А если забивать посимвольно, то строка будет иметь вид "1 1 + ="

lxa85
13-04-2014, 11:11
Prof, собственно и я о том.
А ввод строки так и не был показан.

Prof
13-04-2014, 17:07
lxa85, так вышенаписанным циклом for и формируется строка line. Изначально она пустая, note вводим с клавиатуры, потом этим циклом разбираем поэлементно, space_add() просто добавляет пробел.
Или я, всё-таки, не понял суть вопроса?

lxa85
13-04-2014, 19:14
Prof, ты прав, формируется строка line. Входным аргументом для нее является note.
Вопрос был о том, как формируется note, и как вызывается функция анализа.
Можно было псевдокодом.
Цикл
Ввод одного символа \\ например "1\0"
вызов процедуры
Конец цикла
В одном случае (посимвольном) будет передаваться короткая строка "1\0", "+\0", "1\0" и т.д.
А в другом "1+1".
----
Т.е. изначально было предположение, что код циклиться, потому что передаются короткие строки (т.е. посимвольный ввод осуществлен не совсем правильно). Хотелось увидеть этому опровержение/доказательство.




© OSzone.net 2001-2012