Variable in C von string auf hexadezimal casten

Herakles

Profifragensteller
Moin moin!

Ich lese aus einer Datei einen Wert mit

Code:
fscanf( f_in, "%s %s\n", param, value );

ein. Die variable Value erhält dabei manchmal einen String, der auch als string interpretiert werden soll (also zum Beispiel das Wort toll), manchmal aber auch einen hexadezimalen Wert (also zum Beispiel die Zahl 5A).

Gibt es eine Möglichkeit, die Variable "value" hexadezimal zu casten? Also dem Rechner zu sagen:

nimm das Zeichen, was in der Variablen steht, als hexadezimalen Wert!

würde ich ein

Code:
fscanf( f_in, "%s [B]%x[/B]\n", param, value );

machen, hätte ich zwar den gewünschten Effekt, könnte dann aber Worte nicht mehr lesen (wie beispielsweise das genannte Wort toll).

Danke für jede Hilfe, Herakles
 
Vielleicht meinst du so etwas? Ist c++ Code, sollte sich aber konvertieren lassen.
Code:
/**
 * This is thrown by the getIntFromString function to indicate that the base
 * is invalid.
 */
const exception IncorrectBaseException;

/**
 * This is thrown by getIntFromString and wrappers if the giben string contains
 * invalid characters.
 */
const exception BadCharacterException;

/**
 * This function returns the integer value of a string. An exception will be
 * thrown if a base higher than 32 is offered (for lack of symbols). The string
 * will be stripped of spaces and tabs. The first character may be '-' or '+',
 * any other character that is not a numerical value (what is a numerical value
 * depends on the given base), will cause an exception to be thrown.
 * 
 * @param	number	A string formated number.
 * @param	base	The base of the number.
 * @return	The integer value of number.
 * @throws	IncorrectBaseException
 * @throws	BadCharacterException
 */
int getIntFromString(string number, int base) {
	// We only know 32 symbols, so 32 is the largest base.
	if (base > 32 || base < 2)
		throw IncorrectBaseException;

	// Remove spaces.
	for (int i = 0; i < (int)number.length(); i++)
		if (number[i] == ' ' || number[i] == '	')
			number = number.erase(i--, 1);

	// A list of characters that require conversion.
	char convert[] = {
		' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		' ', ' ', 'A', 'B', 'C', 'D', 'E', 'F',
		'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
		'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'
	};

	// A list of valid symbols.
	char symbols[] = {
		'0', '1', '2', '3', '4', '5', '6', '7',
		'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
		'o', 'p', 'q', 'r', 's', 't', 'u', 'v'
	};
	
	// Convert characters to the respective symbols.
	for (int i = 0; i < (int)number.length(); i++)
		for (int p = 0; p < base; p++)
			if (number[i] == convert[p]) {
				number[i] = symbols[p];
				break;
			}
	
	// Deal with '+' and '-'.
	bool negative = false;
	if (number[0] == '-') {
		negative = true;
		number = number.erase(0, 1);
	} else if (number[0] == '+')
		number = number.erase(0, 1);
	
	// Initialize variables to store the result and the factor (base^(n-i-1)).
	int result = 0;
	int factor = 1;
	for (int i = number.length() - 1; i >= 0; i--) {
		int value = -1;
		
		// Find the value of the current character.
		for (int p = 0; p < base; p++)
			if (number[i] == symbols[p]) {
				value = p;
				break;
			}
		
		// There was a forbidden symbol.
		if (value == -1)
			throw BadCharacterException;
		
		// Add the value to the result, using the proper factor.
		result += value * factor;
		// Increase the factor for the next digit.
		factor *= base;
	}
	
	if (negative)
		return - result;
	return result;
}
 
spontan wuerde ich das so machen:
Code:
int gethex(unsigned char *s, int n)
{

int i;
int l=strlen(s);
int j,k;
unsigned char hexit[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
unsigned char c;
unsigned int x=0;


for (i=0;(i<n) && (i<l);i++)
{
c=s[i];
k=-1;
for (j=0;(k==-1)&&(j<10);j++)
{ 
if (c==hexit[j]) k=j;
}
c|=32; // lower case
for (j=10;(k==-1)&&(j<16);j++)
{
if (c==hexit[j]) k=j;
}

if (k==-1) return -1;
x<<=4;
x|=k;

}


return x;
}

wenn das ding -1 zurueckgibt dann wars garantiert keine hexzahl.

quizfrage...
was machst du bei AFFE? ;)
 
Zuletzt bearbeitet:
Zu allererst einmal Danke an alle Kamikaze und Dettus.

Näher angeschaut habe ich mir den kompakteren Code von Dettus und einen kleinen Fehler entdeckt: Du hast vergessen, k mit -1 zu initialisieren. Der korrekte Code sähe dann so aus:

Code:
int gethex(unsigned char *s, int n) {

	int i;
	int l = strlen( s );
	int j, k;
	unsigned char hexit[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
	unsigned char c;
	unsigned int x = 0;
	k = -1;
	for ( i = 0; ( i < n ) && (i < l); i++ ) {
		c = s[i];
		for ( j = 0; ( k == -1 ) && ( j < 10 ); j++ )
			if ( c == hexit[j] ) k = j;
		c |= 32; // lower case
		for ( j = 10; ( k == -1 ) && ( j < 16 ); j++ )
			if ( c == hexit[j] ) k = j;
		if ( k == -1 ) {
			printf("HEX-Error in MAC!\n");
			return -1;
		}
		x <<= 4;
		x |= k;
		k = -1;
	}

 	return x;
}

Und Dettus... die Quizfrage... ist das ein Insider?

Danke, Herakles
 
@paefchen: jetzt hab ichs geschnallt. Bin wohl deswegen nicht auf den Witz gekommen, weil bei mir anhand des vorangestellten "param" Wertes schon klar ist, ob es ein String oder ein hexadezimaler Wert ist...

Aber nun hab ich den Witz. Also: HAHA! (wenn es denn überhaupt ein Witz sein sollte).

Folgefrage nun aber: im Prinzip will ich an dieser Stelle MAC-Adressen einlesen. Nehmen wir mal den (unmöglichen) Fall einer MAC-Adresse dieses Wertes an:

FF:FF:FF:FF:FF:FF

Hier hätte man einen Dezimalwert von 281474976710655, das sind 15 Stellen. Ein int kann jedoch nur 10 Stellen aufnehmen. Wie also lese ich nu eine solche MAC ein??? Die Doppelpunkte zu überlesen ist ja Kinderkram, es geht also um den Wert der Adresse...

Herakles
 
Zurück
Oben