Comment puis-je détecter un opérateur contre int en C en utilisant scanf?
-
23-09-2019 - |
Question
Comment puis-je lire dans l'entrée suivante dans ma calculatrice RPN afin qu'il trouvera l'opérateur peu importe quel ordre?
2
2+
4
A partir de maintenant mon scanf ne voit que le premier caractère dans la chaîne et je ne peux faire ceci:
2
2
+
4
Je suis aussi essayer d'ajouter une option pour entier vs flottant en mode point. (Ex. Lorsque 'i' est entré, fonctionnent en virgule flottante et vice versa.)
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int *p;
int *tos;
int *bos;
void push(int i);
int pop(void);
int main (void)
{
int a, b;
//float c, d;
char s[80];
//char op; //declare string of 80 chars
p = (int *) malloc(MAX*sizeof(int)); //get stack memory
if (!p){
printf("Allocation Failure\n");
exit(1);
}
tos = p;
bos = p + MAX-1;
printf("\nRPN Calculator\n");
printf("Enter 'i' for integer mode\n");
printf("Enter 'f' for floating point mode\n");
printf("Enter 'q' to quit\n");
do {
printf("> ");
// gets(s);
// scanf("%s", s); //read integer
scanf("%s", s);
// switch (*s) {
switch(*s) {
case 'i':
printf("(Integer Mode)\n");
break;
case 'f':
printf("(Floating Point Mode)\n");
break;
case '+':
a = pop();
b = pop();
printf("%d\n", a+b);
push(a+b);
break;
case '-':
a = pop();
b = pop();
printf("%d\n", b-a);
push(b-a);
break;
case '*':
a = pop();
b = pop();
printf("%d\n", a*b);
push(a*b);
break;
case '/':
a = pop();
b = pop();
if(a == 0){
printf("Cannot divide by zero\n");
break;
}
printf("%d\n", b/a);
push(b/a);
break;
case '.':
a = pop();
push(a);
printf("Current value on top of stack: %d\n", a);
break;
default:
push(atoi(s));
}
} while (*s != 'q');
return 0;
}
// Put an element on the stack
void push (int i)
{
if (p > bos){
printf("Stack Full\n");
return;
}
*p = i;
p++;
}
// Get the element from the top of the stack
int pop (void)
{
p--;
if(p < 0) {
printf("Stack Underflow\n");
return 0;
}
return *p;
}
La solution
Votre scanf
lit toute la chaîne. Il est le commutateur suivant que les juges par le premier caractère et qui manque +
dans 2+
.
Pour améliorer, vous pouvez utiliser la fonction strtol
. Il analysera un entier de la chaîne et retourner à l'endroit où vous l'entier a pris fin - si c'est pas encore la fin de la chaîne, il peut y avoir un opérateur il
Une fonction similaire pour les nombres à virgule flottante est strtod
.
Voici quelques exemples de code de strtol
applicable à votre exemple:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* input = "25+";
char* endptr;
int val = strtol(input, &endptr, 10);
if (*endptr == '\0')
{
printf("Got only the integer: %d\n", val);
}
else
{
printf("Got an integer %d\n", val);
printf("Leftover: %s\n", endptr);
}
return 0;
}
Autres conseils
Je ne sais pas si je comprends bien votre question, mais vous pouvez itérer la chaîne comme ceci:
for(i = 0; i < strlen(s); i++)
{
// Here comes your switch section like this
switch(s[i]) {
.....
}
}
Rappelez-vous également inclure string.h.
Je ne comprenais pas vraiment votre code.
Si vous attendez l'utilisateur d'entrer un caractère à chaque fois, je veux dire un caractère + entrer, vous devez utiliser un simple caractère au lieu de char []. Et si vous faites semblant d'utiliser une chaîne que vous devriez le recevoir et l'analyser pzico dit. Vous pourriez faire quelque chose comme ça. Le problème serait dans le traitement des nombres avec plusieurs chiffres, mais en pensant un peu, vous pouvez résoudre ce problème. J'ai écrit une tentative, mais je suis sûr qu'il ne va pas au travail.
printf ( "\ nrpn Calculator \ n");
printf ( " 'i' ENTER pour le mode entier \ n");
printf ( "Entrez 'f' pour le mode virgule flottante \ n");
printf ( "Enter 'q' pour quitter \ n");
scanf ( "% c", s);
commutateur (* s) {
case 'i':
printf("(Integer Mode)\n");
break;
case 'f':
printf("(Floating Point Mode)\n");
break;
case 'q':
printf("Bye Bye\n");
return;
break;
} printf ( "Entrez l'expression d'un caractère à chaque fois \ n");
faire {
scanf("%c", s);
switch(s) {
case '+':
a = pop();
b = pop();
printf("%d\n", a+b);
push(a+b);
break;
case '-':
a = pop();
b = pop();
printf("%d\n", b-a);
push(b-a);
break;
case '*':
a = pop();
b = pop();
printf("%d\n", a*b);
push(a*b);
break;
case '/':
a = pop();
b = pop();
if(a == 0){
printf("Cannot divide by zero\n");
break;
}
printf("%d\n", b/a);
push(b/a);
break;
case '.':
a = pop();
push(a);
printf("Current value on top of stack: %d\n", a);
break;
default:
a = pop()*10+atoi(s);
push(a);
}
} while (s = 'q'!);
Un autre problème dans votre code est dans votre fonction pop. Que voulez-vous faire avec ce test:
if (p <0) {
printf ( "Stack Underflow \ n");
return 0;
}
Vous attendez votre pointeur pour atteindre l'adresse 0?
En tout cas j'espère que ce n'est pas vos devoirs.