Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Πολυ-καλησπερίζω το πλήθος,

 

 

 

#include <stdio.h>
#include <regex>

using namespace std;

// Some Limits
#define MIN 0x0000
#define MAX 0xFFFF		// Btw, ushort int max is 0xFFFF, why need this? ... anyway

// Functions Signature
bool isValidInput(char *input);
bool isOverflowed(unsigned short int);
bool isUnderflowed(unsigned short int);
unsigned short int Calculate(char *input);
char* FormatResult(char *result);


int main()
{

	// Input
	char *input;
	input = (char *)malloc(sizeof(char) * 20);

	if (input != NULL)
	{
		while (true)
		{
			scanf("%s", input);
		
			if (isValidInput(input))
			{
				printf("Result: %u\n", Calculate("23+"));
			}
			else
			{
				printf("ERROR");
			}
		}
	}
	else
		printf("ERROR");
	
	return 0;
}

bool isValidInput(char *input)
{
	return (regex_match(input, regex("^[a-fA-F0-9]{2}[\-\+\*\/]$")));
}

bool isOverflowed(unsigned short int value)
{
	return (value > MAX);
}

bool isUnderflowed(unsigned short int value)
{
	return (value < MIN);
}

unsigned short int Calculate(char *input)
{
	unsigned short int x, y, result;
	char symbol;

	x = atoi(&input[0]);
	y = atoi(&input[1]);
	symbol = input[2];
	
	// Debug
	printf("\nInput:%s\n", input);
	printf("\nx/y = %u / %u\n", x, y);
	printf("\n--------\n");

	switch (symbol)
	{
		case '+':
			result = x + y;
			break;
		case '-':
			result = x - y;
			break;
		case '*':
			result = x * y;
			break;
		case '/':
			result = x / y;
			break;
	}

	return result;

}
char* FormatResult(char *result)
{

	return "TODO";
} 

 

 

 

Το πρόβλημα μου είναι ότι όταν πάω να κάνω Parse ένα String της μορφής "FF+" (Αριθμός, Αριθμός και σύμβολο της πράξης) ->

// input = "F2+"
...

int x = atoi(input[0]);
int y = atoi(input[1]);
char symbol = input[2];

switch(symbol)
{
    ....
}

Το πρόβλημα είναι: 

x = F2+      // this should be 'F'

y = 2

symbol = +

 

Με απλά Ελληνικά, έχει πρόβλημα με την θέση 0, δεν μπορώ να κάνω cast γιατί παίρνει όλο το String αντί μόνο του 1ου χαρακτήρα.

 

Κάποια λύση; 

  • Moderators
Δημοσ.

Αν θες να δουλεύεις μόνο με μονοψήφια νούμερα (δηλαδή το input σου είναι πάντα 2 αριθμοί κι ένα σύμβολο πράξης) τότε μπορείς να κάνεις κάτι τέτοιο.

Δημοσ.

Ένα άλλο λάθος είναι ότι η atoi περιμένει ένα C-style (null terminated) string και αυτό που της δίνεις εσύ (νομίζοντας πως είναι ένα μόνο ψηφίο) δεν είναι αυτό που περιμένεις.

 

Επίσης υπόψιν αυτό δεν είναι C αλλά C++. Εδώ δεν έχει διαφορά σε κάτι, γενικά όμως μπορεί να έχει.

 

Ακόμα, δε βλέπω να κάνεις κάτι με τις isUnderflowed και isOverflowed, αλλά είναι και οι δύο λάθος γιατί δεν υπάρχει ποτέ περίπτωση να επιστρέψουν false.


c=tolower(c);
if(c >= 'a' && c <= 'f')
	return c - 'a' + 10;

 

Nitpick: technically δε μπορείς να το υποθέσεις. Στην πράξη φυσικά ισχύει.

Δημοσ.

Ένα άλλο λάθος είναι ότι η atoi περιμένει ένα C-style (null terminated) string και αυτό που της δίνεις εσύ (νομίζοντας πως είναι ένα μόνο ψηφίο) δεν είναι αυτό που περιμένεις.

 

Επίσης υπόψιν αυτό δεν είναι C αλλά C++. Εδώ δεν έχει διαφορά σε κάτι, γενικά όμως μπορεί να έχει.

 

Ακόμα, δε βλέπω να κάνεις κάτι με τις isUnderflowed και isOverflowed, αλλά είναι και οι δύο λάθος γιατί δεν υπάρχει ποτέ περίπτωση να επιστρέψουν false.

 

Nitpick: technically δε μπορείς να το υποθέσεις. Στην πράξη φυσικά ισχύει.

 

Το γράφω στα σχόλια αυτό που λες.

 

Βασικά... υποτίθεται ότι έχεις μια ακολουθία αριθμών : "FF+ 23- F5* 6B/ 5C*" ... και πρέπει να τα κάνεις όλα αυτά και να βγάλεις τον τελικό αριθμό... έτσι ναι! ξεπερνάς το MaxInt.

 

Αυτό που έκανα εγώ, Pars-αρει μόνο 1 ομάδα και δεν θα χρησιμεύσουν οι Overflowed/Underflowed.

 

-----

 

Btw, μάλλον θα βάλω Linux(μιας και τα τεστς γινονται σε λινουχ) να συμβαδίζω με αυτά που ζητάνε γιατί έχω θέματα με συναρτήσεις που δεν είναι standart. Δηλαδή η strrev(...) είναι Custom μάλλον γιατί μόνο στο VS την έχει, στο PellesC99Mode δεν την έχει. Ούτε το Σιτε που ποσταρω τον κώδικα την αναγνωρίζει...  

Δημοσ.

Βασικά... υποτίθεται ότι έχεις μια ακολουθία αριθμών : "FF+ 23- F5* 6B/ 5C*" ... και πρέπει να τα κάνεις όλα αυτά και να βγάλεις τον τελικό αριθμό... έτσι ναι! ξεπερνάς το MaxInt.

 

Αυτό που έκανα εγώ, Pars-αρει μόνο 1 ομάδα και δεν θα χρησιμεύσουν οι Overflowed/Underflowed.

Ναι ΟΚ, αλλά αυτό που θέλω να πω είναι ότι πρώτον συγκρίνεις ένα unsigned int με κάτι που δεν είσαι σίγουρος τι είναι, γιατί το literal 0xFFFF είναι σύμφωνα με το πρότυπο κάποιος κατάλληλος αριθμητικός τύπος που να μπορεί να αναπαραστήσει την τιμή 0xFFFF. Μπορεί εσύ να βάλεις κάτι μεγαλύτερο από το maximum του unsigned int.

 

Επίσης στο underflow λέει "if unsigned int < 0". Προφανώς αυτό δε μπορεί να γίνει ποτέ, γιατί δε γίνεται unsigned τιμή να είναι < 0 ο,τι κι αν κάνεις (το πρότυπο λέει πως υπάρχει αυτόματο wrap-around).

Δημοσ.

 

// Some Limits
#define MIN 0x0000
#define MAX 0xFFFF		// Btw, ushort int max is 0xFFFF, why need this? ... anyway

bool isOverflowed(unsigned short int value)
{
	return (value > MAX);
}

bool isUnderflowed(unsigned short int value)
{
	return (value < MIN);
}

 

Όπως σου είπε και ο defacer, οι δύο αυτές συναρτήσεις δεν έχουν νόημα. Η underflow δεν έχει νόημα γιατί δεν μπορεί να υπάρξει unsigned αριθμός ο οποίος να είναι μικρότερος του μηδενός ενώ η overflow δεν έχει νόημα γιατί δεν είναι γραμμένη καλά.

 

Λες στο σχόλιο ότι η μέγιστη τιμή ενός ushort 0xFFFF. Ενώ δεν ισχύει αυτό ας δεχτούμε για μια στιγμή ότι είναι έτσι. Όταν έχεις ένα σακί που χωράει 500 φασόλια δεν υπάρχει λόγος να ψάξεις αν μέσα υπάρχουν 501 φασόλια μια και δεν γίνεται αφού το μέγιστο είναι 500. Με το ίδιο σκεπτικό τι νόημα έχει ο έλεγχος value > MAX ? Εφόσον στην συνάρτηση περνάς ένα όρισμα τύπου unsigned short, αυτό αναγκαστικά μπορεί να αναπαραστήσει το πολύ MAX τιμή ακόμη και μεγαλύτερη τιμή να δώσεις στο κάλεσμα της συνάρτησης οπότε ο έλεγχος είναι περιττός.

 

Για του λόγου το αληθές, ο gcc με ενεργοποιημένη την βελτιστοποίηση παράγει τον παρακάτω κώδικα:

isOverflowed:
	xorl	%eax, %eax
	ret
isUnderflowed:
	xorl	%eax, %eax
	ret
δηλαδή η συνάρτηση επιστρέφει πάντα μηδέν χωρίς να κάνει κανένα έλεγχο.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...