char conversion problem

M

muser

is string converted to its integer equivalent by minusing it by 48?
the function is suppose to check the fifth digit of struct member
using the formula contained within the function.
The function isn't doing that at the moment, hence this post and the
querie above. string must be of type char.



bool checkdigitforcustomercode( char* string )
{

int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;



for(int i =0; i < 5; ++i)
check1 += (string - 48) * weightingfactor;/* problem area */
weightingfactor --;


remainder = check1 % 11;

checkdigit = 11 - remainder;

for(i=4; i<=5; i++)
if(!string == checkdigit)
return false;


if(checkdigit == 11){
checkdigit = 'X';
}
else
if(checkdigit = 10){
checkdigit = '0';
}

return true;
}
 
J

Joe C

muser said:
is string converted to its integer equivalent by minusing it by 48?

If you want to strip numbers from the ASCII code, I'd think you would want
to do it as follows...first, check that the char is in the range 48-57, then
take the char and "bit_and" it with binary integer 1111. The result will be
the decimal numeric equivalent to the ascii number. There's prob many
"better" ways to do this. However, if you need to process a bunch of data,
some similar method is likely efficient.

I'd use something like:

#include<iostream>

using namespace std;

int num_seeker(char charin){
return ((47 < charin) && (charin < 58)) ? charin & 15 : -1;
}

int main(){
char g;

for(int i = 0; i < 256; ++i){
g = i;
cout << i <<" "<< g <<" "<< num_seeker(g) << endl;
}

return 0;
}
 
V

Victor Bazarov

muser said:
is string converted to its integer equivalent by minusing it by 48?

No. But to convert a decimal digit in most codes (all codes that
I know of) to its decimal "value" you need to subtract '0' (zero
digit).

If you need to convert a string (are you talking of std::string?)
into its integer "equivalent", use 'std::istringstream'.
the function is suppose to check the fifth digit of struct member
using the formula contained within the function.
The function isn't doing that at the moment, hence this post and the
querie above. string must be of type char.

"Isn't doing" WHAT at the moment? What "formula" should it use?
If the code doesn't do what's expected of it, how should we be able
to recommend anything?
bool checkdigitforcustomercode( char* string )
{

int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;



for(int i =0; i < 5; ++i)
check1 += (string - 48) * weightingfactor;/* problem area */


If it's only the _fifth_ digit you need to check, why are you subtracting
_all_ of them?

If what you're trying to do here is to convert the five leading characters
of the 'string' array into a decimal number _manually_, that's not the right
way. The right way would be

check1 = (check1 * 10) + string - '0';

(and (a) don't forget to initialise 'check1' to 0, and (b) there is a strong
assumption that all 'string' elements contain _decimal_digits_).
weightingfactor --;


remainder = check1 % 11;

Why "% 11"? Shouldn't it be "% 10"? And if you just need the 5th digit,
why not just take string[4] and look at it?

Your programming exercises are beyond me, to be honest with you. Where
are you getting all that stuff?

Try to do this: if you need something _corrected_, _describe_carefully_
what you think it should do. Please try to avoid using "the formula
contained within the function" description. If you didn't do it right,
there is _no_ formula.
checkdigit = 11 - remainder;

for(i=4; i<=5; i++)
if(!string == checkdigit)
return false;


if(checkdigit == 11){
checkdigit = 'X';
}
else
if(checkdigit = 10){
checkdigit = '0';
}

return true;
}
 
V

Victor Bazarov

Joe C said:
If you want to strip numbers from the ASCII code, I'd think you would want
to do it as follows...first, check that the char is in the range 48-57, then
take the char and "bit_and" it with binary integer 1111. The result will be
the decimal numeric equivalent to the ascii number. There's prob many
"better" ways to do this. However, if you need to process a bunch of data,
some similar method is likely efficient.

I'd use something like:

#include<iostream>

using namespace std;

int num_seeker(char charin){
return ((47 < charin) && (charin < 58)) ? charin & 15 : -1;

NEVER use straight values when working with characters, it's completely
unportable. You _ought_ to just use '0' and '9' (to form the expression

('0' <= charin && charin <= '9')
 
K

Karl Heinz Buchegger

muser said:
is string converted to its integer equivalent by minusing it by 48?

You mean: a single character, not a string.

Yes, you can do that. But do yourself a favour and replace 48
with '0'.

int AsInt;
char AsChar = '8';

AsInt = AsChar - '0';

AsInt now contains the value 8.
the function is suppose to check the fifth digit of struct member
using the formula contained within the function.
The function isn't doing that at the moment, hence this post and the
querie above. string must be of type char.

bool checkdigitforcustomercode( char* string )
{

int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;

for(int i =0; i < 5; ++i)
check1 += (string - 48) * weightingfactor;/* problem area */
weightingfactor --;


That looks strange. What is it supposed to do?

If you want to convert "32078" into an integer, then
you simply can do:

sscanf( string, "%d", &check );

But note: a 5 digit string, eg. "78542", may overflow
an int on some systems, noteable those where the maximum
signed int is 32768. So you'd better check that.

If you want to do it the hard way (by hand, insted of
sscanf) it is done this way:

check1 = 0;
for( int i = 0; i < 5; ++i )
{
check1 = 10 * check1;
check1 += string - '0';
}

Consider the string "29671"
Check1 starts with a value of 0. Now the for
loop begins:

i = 0
Check1 * 10 -> 0
'2' - '0' -> 2 + Check1 -> 2

i = 1
Check1 * 10 -> 20
'9' - '0' -> 9 + Check1 -> 29

i = 3
Check1 * 10 -> 290
'6' - '0' -> 6 + Check1 -> 296

i = 4
Check1 * 10 -> 2960
'7' - '0' -> 7 + Check1 -> 2967

i = 5
Check1 * 10 -> 29670
'1' - '0' -> 1 + Check1 -> 29671

Finshed: The string "29671" has been converted to its
numerical equivalent 29671


The other thing your code:
for(int i =0; i < 5; ++i)
check1 += (string - 48) * weightingfactor;/* problem area */
weightingfactor --;


could mean, is some sort of checksum over the digits, where
each digit has a different weight.
But then I guess it has to read:

for(int i =0; i < 5; ++i)
{
check1 += (string - 48) * weightingfactor;/* problem area */
weightingfactor --;
}

Note that the decrement of the weightingfactor is now enclosed
in the loop and each digit gets a different weightingfactor.
(Without that, the whole concept of weightingfactor wouldn't make
any sense, since the weightingfactor isn't used anywhere else in
your function).

Another tip: If you think that some computation doesn't work the
way you think it should, it is always a good idea to either
* use a debugger to check the variables
* or insert some outputstatements which shed some light on what
is going on:

for( int i = 0; i < 5; ++i )
{
printf( "Check1: %d, String[%d] %c, Weight %d -> ",
check1, i, string, weightingfactor );

check1 += (string - 48) * weightingfactor;/* problem area */

printf( "%d\n", check1 );
}

Then you can see on your monitor what is going on and will be able to
check the computation. Once you understand what is going on and what
is wrong with that: fix the computation, use the output to verify that
it now works as you expect it to work and remove those additional output
statements.
 
J

Joe C

Victor Bazarov said:
NEVER use straight values when working with characters, it's completely
unportable. You _ought_ to just use '0' and '9' (to form the expression

('0' <= charin && charin <= '9')

Better yet, use 'std::isdigit' function from <cctype>.

Victor, Thanks for the kick in the tail...again ;-)

I actually misread the original post...I thought he was stripping numbers
from a serial number/barcode type thingie...where portability would be
non-important.

on my original code...if you had a large file that contained a boatload of
ascii data to sort through...you could speed up my function a bit by using:

int num_seeker(char charin){
return (charin > 57) ? -1 : ((charin < 48) ? -1 : charin & 15);
}
That way you'd get your return value after just 1 comparison for all
characters (likely to be the most frequent) performing the second comparison
only if needed.

Victor...I respect your thoughts a lot. Would you ever do something like
this, or is it simply offensive to your programming sensibilities?
 
K

Karl Heinz Buchegger

Joe said:
Victor, Thanks for the kick in the tail...again ;-)

I actually misread the original post...I thought he was stripping numbers
from a serial number/barcode type thingie...where portability would be
non-important.

on my original code...if you had a large file that contained a boatload of
ascii data to sort through...you could speed up my function a bit by using:

int num_seeker(char charin){
return (charin > 57) ? -1 : ((charin < 48) ? -1 : charin & 15);
}
That way you'd get your return value after just 1 comparison for all
characters (likely to be the most frequent) performing the second comparison
only if needed.

Victor...I respect your thoughts a lot. Would you ever do something like
this, or is it simply offensive to your programming sensibilities?


Can't talk for Victor.
But even then I would do:

return (charin > '9') ? -1 : ((charin < '0') ? -1 : charin - '0');

Much simpler to not have to remember the code values for the digits.
(On most CPU's I think its reasonable to assume that a subtraction
runs in the same time as an and masking).
 
V

Victor Bazarov

Karl Heinz Buchegger said:
Can't talk for Victor.
But even then I would do:

return (charin > '9') ? -1 : ((charin < '0') ? -1 : charin - '0');

Much simpler to not have to remember the code values for the digits.
(On most CPU's I think its reasonable to assume that a subtraction
runs in the same time as an and masking).

Karl, you read my mind. Couple more of these and I'll let you talk
for me. :)))

Victor
 
G

Gene Wirchenko

On Wed, 17 Dec 2003 20:26:06 +0100, Karl Heinz Buchegger

[snip]
Can't talk for Victor.
But even then I would do:

return (charin > '9') ? -1 : ((charin < '0') ? -1 : charin - '0');

Much simpler to not have to remember the code values for the digits.
(On most CPU's I think its reasonable to assume that a subtraction
runs in the same time as an and masking).

It also has the advantage that it does not depend on the
character set being ASCII.

Sincerely,

Gene Wirchenko
 
J

Jerry Coffin

is string converted to its integer equivalent by minusing it by 48?

No. A single character might be, depending on the character set in use,
but a character is not a string.

If I'm reading your code correctly, I'd use something like this:

for (i=0; i<5;i++)
if ( isdigit(string))
check1 += (string-'0') * weightingfactor--;

The part where you have 'if (checkdigit = 10)' is almost certainly an
error -- you're doing an assignment instead of a comparison. In any
case, I'd probably cheat, and make this table-driven:

char digits[] = "01234567890X";

// loop from above.

checkdigit = digits[11 - (check1 % 11)];

I'm not quite sure I follow your 'if (!string == checkdigit)'.
Perhaps you wanted: 'if (string != checkdigit)'? comparison ('==')
has lower precedence than logical negation ('!'), so as-is, you're doing
logical negation on 'string', and then comparing the result of that
to checkdigit. Logical negation is _normally_ done on a logical value,
and it looks like string will be a character rather than boolean.
 
M

muser

Jerry Coffin said:
is string converted to its integer equivalent by minusing it by 48?

No. A single character might be, depending on the character set in use,
but a character is not a string.

If I'm reading your code correctly, I'd use something like this:

for (i=0; i<5;i++)
if ( isdigit(string))
check1 += (string-'0') * weightingfactor--;

The part where you have 'if (checkdigit = 10)' is almost certainly an
error -- you're doing an assignment instead of a comparison. In any
case, I'd probably cheat, and make this table-driven:

char digits[] = "01234567890X";

// loop from above.

checkdigit = digits[11 - (check1 % 11)];

I'm not quite sure I follow your 'if (!string == checkdigit)'.
Perhaps you wanted: 'if (string != checkdigit)'? comparison ('==')
has lower precedence than logical negation ('!'), so as-is, you're doing
logical negation on 'string', and then comparing the result of that
to checkdigit. Logical negation is _normally_ done on a logical value,
and it looks like string will be a character rather than boolean.


Thank you Victor and Karl for responding to my previous post. Jeff
you've actually spotted the problem with comparing if(!string ==
checkdigit), as i actually just came online to ask why the
checkdigitforcustomercode wasn't working (citing that exactly line of
code as a contentious area).
Karl and Victor I did use your advice and have remedied most of the
problem using quick watch and other debugging tools.
To get one of the two 'big boys' of these newsgroups to respond to a
post is a quite a feat, to get both is unprecendented, and I thank you
one and both for your advice.
 
O

Old Wolf

But even then I would do:
It also has the advantage that it does not depend on the
character set being ASCII.

Actually it does; there's no reason that 0-9 have to be contiguous in
the character set. (Hence the reason for using the <cctype> functions,
if you are a portability freak).
 
J

Jerry Coffin

[ ... ]
Actually it does; there's no reason that 0-9 have to be contiguous in
the character set.

The C++ standard requires that 0-9 be contiguous in the character set.
 
R

Ron Natalie

Jerry Coffin said:
[ ... ]
Actually it does; there's no reason that 0-9 have to be contiguous in
the character set.

The C++ standard requires that 0-9 be contiguous in the character set.
Yes, but it doesn't hold true for the letters. Nobody here probably knows
what "Junior is 11" means.
 
M

muser

I've put this code through the debugger a couple of times and still
I'm unable to find the problem.
The checkdigit is correct, the remainder variable is correct. But when
I check the char string variable, I get a memory address. The function
works all except when I get to the definitive line if(string1[4] !=
checkdigit) return false;


bool checkdigitforcustomercode( char* string )
{

int checkdigit;
int remainder;
int product;
int string1[5];


string1[0] = string[0] - 0;
string1[1] = string[1] - 0;
string1[2] = string[2] - 0;
string1[3] = string[3] - 0;
string1[4] = string[4] - 0;


product = (string[0] * 5) + (string[1] * 4) + (string[2] * 3) +
(string[3] * 2);

remainder = (product % 11);

checkdigit = (11 - remainder);


if(string1[4] != checkdigit){}
return false;



return true;
}

I have tried putting the zeroes in single quotation marks e.g. '0'.
And putting brackets around the equation string1[0] = (string[0] - 0);
the string contains numbers 24686, the last digit is a six, and the
checkdigit is a six, so the function is suppose to return true, but
doesn't. It returns false.

if(!checkdigitforcustomercode( rec.Newcrecord.customercode )){
prnfile<< "Invalid: Incorrect check digit for c record customer
code\n";
prnfile<< record << endl;
return false;
}

rec is the object of a union, and Newcrecord is the object of a
struct.





Jerry Coffin said:
is string converted to its integer equivalent by minusing it by 48?

No. A single character might be, depending on the character set in use,
but a character is not a string.

If I'm reading your code correctly, I'd use something like this:

for (i=0; i<5;i++)
if ( isdigit(string))
check1 += (string-'0') * weightingfactor--;

The part where you have 'if (checkdigit = 10)' is almost certainly an
error -- you're doing an assignment instead of a comparison. In any
case, I'd probably cheat, and make this table-driven:

char digits[] = "01234567890X";

// loop from above.

checkdigit = digits[11 - (check1 % 11)];

I'm not quite sure I follow your 'if (!string == checkdigit)'.
Perhaps you wanted: 'if (string != checkdigit)'? comparison ('==')
has lower precedence than logical negation ('!'), so as-is, you're doing
logical negation on 'string', and then comparing the result of that
to checkdigit. Logical negation is _normally_ done on a logical value,
and it looks like string will be a character rather than boolean.
 
V

Victor Bazarov

muser said:
[...]
string1[0] = string[0] - 0;
string1[1] = string[1] - 0;
string1[2] = string[2] - 0;
string1[3] = string[3] - 0;
string1[4] = string[4] - 0;


Subtracting 0 from anything usually doesn't do anything. Do you
really think it does? What do you think you're accomplishing here?
product = (string[0] * 5) + (string[1] * 4) + (string[2] * 3) +
(string[3] * 2);

Why are you multiplying by 5, 4, 3, and 2 here? What happened to
string[4]? How come it's not participating?
remainder = (product % 11);

What is that for?
checkdigit = (11 - remainder);

What is that supposed to do?
if(string1[4] != checkdigit){}

What are the curly braces after the 'if' expression?
return false;



return true;
}

I have tried putting the zeroes in single quotation marks e.g. '0'.
And putting brackets around the equation string1[0] = (string[0] - 0);
the string contains numbers 24686, the last digit is a six, and the
checkdigit is a six, so the function is suppose to return true, but
doesn't. It returns false.

Wow... You _have_ tried everything. I don't even know what to suggest.

To be honest with you, I see NO HOPE for you. You should stop wasting
your time. Go paint, or play guitar, or ... In any case, programming is
simply not your thing. Once you realise that, you'll be free.
 
C

Christof Krueger

muser said:
I've put this code through the debugger a couple of times and still
I'm unable to find the problem.
The checkdigit is correct, the remainder variable is correct. But when
I check the char string variable, I get a memory address. The function
works all except when I get to the definitive line if(string1[4] !=
checkdigit) return false;


bool checkdigitforcustomercode( char* string )
{

int checkdigit;
int remainder;
int product;
int string1[5];


string1[0] = string[0] - 0;
string1[1] = string[1] - 0;
string1[2] = string[2] - 0;
string1[3] = string[3] - 0;
string1[4] = string[4] - 0;
You need to put the zeros in single quotation marks.
product = (string[0] * 5) + (string[1] * 4) + (string[2] * 3) +
(string[3] * 2);

remainder = (product % 11);

checkdigit = (11 - remainder);


if(string1[4] != checkdigit){}
return false;
With the above if-statement you check if string1[4] != checkdigit. Then
follow {}. That means that if the expression in your if-statemant
returns true *nothing happens*. The next line is *not* part of the
if-statement. It is *always* executed.
return true;
}
This return-statement is unreachable becauseof the non-conditional
"return false;" above. The solution is trivial. Set the curly braces at
the right position:

if(string1[4] != checkdigit){
return false;
}
return true;

You should learn to understand what you actually write. You should be
able to find such an error on yourself by going through your program
line by line and thinking about what it will actually do.
I have tried putting the zeroes in single quotation marks e.g. '0'.
And putting brackets around the equation string1[0] = (string[0] - 0);
the string contains numbers 24686, the last digit is a six, and the
checkdigit is a six, so the function is suppose to return true, but
doesn't. It returns false.

if(!checkdigitforcustomercode( rec.Newcrecord.customercode )){
prnfile<< "Invalid: Incorrect check digit for c record customer
code\n";
prnfile<< record << endl;
return false;
}

rec is the object of a union, and Newcrecord is the object of a
struct.
 
M

muser

Victor Bazarov said:
muser said:
[...]
string1[0] = string[0] - 0;
string1[1] = string[1] - 0;
string1[2] = string[2] - 0;
string1[3] = string[3] - 0;
string1[4] = string[4] - 0;


Subtracting 0 from anything usually doesn't do anything. Do you
really think it does? What do you think you're accomplishing here?
product = (string[0] * 5) + (string[1] * 4) + (string[2] * 3) +
(string[3] * 2);

Why are you multiplying by 5, 4, 3, and 2 here? What happened to
string[4]? How come it's not participating?
remainder = (product % 11);

What is that for?
checkdigit = (11 - remainder);

What is that supposed to do?
if(string1[4] != checkdigit){}

What are the curly braces after the 'if' expression?
return false;



return true;
}

I have tried putting the zeroes in single quotation marks e.g. '0'.
And putting brackets around the equation string1[0] = (string[0] - 0);
the string contains numbers 24686, the last digit is a six, and the
checkdigit is a six, so the function is suppose to return true, but
doesn't. It returns false.

Wow... You _have_ tried everything. I don't even know what to suggest.

To be honest with you, I see NO HOPE for you. You should stop wasting
your time. Go paint, or play guitar, or ... In any case, programming is
simply not your thing. Once you realise that, you'll be free.

I had been thinking the same thing victor, (that is to give up and
quit) but now that I've put in so many hours and come this far, I
can't let go like the proverbial dog who has got hold of a bone and
won't let go.
You see if I get this part of the program to work, I will have
finished this part of the course and could in all fairness give up.
What frustrates me is that the code should work and doesn't.

My assignments is this, if you had a load of customers, but wanted to
identify them by code alone you might use a customer code.
(rec.Newcrecord.customercode)These codes are held on a file along with
other customer details from different departments. Some of the
customer codes held on file are wrong, so there is a formula for
checking whether a customer code is right or not.
You * the customer code by a weighting factor (in this instance 5432)
the last customer code digit is a 6, but for the purposes of the
formula it isn't used when validating the customer code.

say customer code is 2468
****
and the weight 5432

the product of this would be 10 + 16 + 18 + 16 = 60;
so the product actually equals 60.
This is then divided by 11 (because all the valid customercodes will
have a modulus 11 checkdigit)
remainder = product % 11;
This produces 5;
subtracting 11 (our mod number) with the remainder gives us 6.
6 being our check digit.
if(string[4] != checkdigit){
return false;
}
or if(string[4] != checkdigit)
return false;
I should have clarified what it was I was trying to achieve.
For all intent purposes when I debug the function
CheckDigitForCustomerCode( char* string )

the product variable contains 60;
the remainder variable contains 5;
the checkdigit variable contains 6;

But the thing is, is that when I go to execute the program my valid
customer code of 24686, comes up as invalid.
I would like to know what could possibly cause this to happen.
string1 is of type integer. string is of type char.
If this or my post is frustrating any members of the newsgroup please
feel reassured that it isn't frustrating you half as much as it is me.
 
M

muser

Victor Bazarov said:
muser said:
[...]
string1[0] = string[0] - 0;
string1[1] = string[1] - 0;
string1[2] = string[2] - 0;
string1[3] = string[3] - 0;
string1[4] = string[4] - 0;


Subtracting 0 from anything usually doesn't do anything. Do you
really think it does? What do you think you're accomplishing here?
product = (string[0] * 5) + (string[1] * 4) + (string[2] * 3) +
(string[3] * 2);

Why are you multiplying by 5, 4, 3, and 2 here? What happened to
string[4]? How come it's not participating?
remainder = (product % 11);

What is that for?
checkdigit = (11 - remainder);

What is that supposed to do?
if(string1[4] != checkdigit){}

What are the curly braces after the 'if' expression?
return false;



return true;
}

I have tried putting the zeroes in single quotation marks e.g. '0'.
And putting brackets around the equation string1[0] = (string[0] - 0);
the string contains numbers 24686, the last digit is a six, and the
checkdigit is a six, so the function is suppose to return true, but
doesn't. It returns false.

Wow... You _have_ tried everything. I don't even know what to suggest.

To be honest with you, I see NO HOPE for you. You should stop wasting
your time. Go paint, or play guitar, or ... In any case, programming is
simply not your thing. Once you realise that, you'll be free.

I had been thinking the same thing victor, (that is to give up and
quit) but now that I've put in so many hours and come this far, I
can't let go like the proverbial dog who has got hold of a bone and
won't let go.
You see if I get this part of the program to work, I will have
finished this part of the course and could in all fairness give up.
What frustrates me is that the code should work and doesn't.

My assignments is this, if you had a load of customers, but wanted to
identify them by code alone you might use a customer code.
(rec.Newcrecord.customercode)These codes are held on a file along with
other customer details from different departments. Some of the
customer codes held on file are wrong, so there is a formula for
checking whether a customer code is right or not.
You * the customer code by a weighting factor (in this instance 5432)
the last customer code digit is a 6, but for the purposes of the
formula it isn't used when validating the customer code.

say customer code is 2468
****
and the weight 5432

the product of this would be 10 + 16 + 18 + 16 = 60;
so the product actually equals 60.
This is then divided by 11 (because all the valid customercodes will
have a modulus 11 checkdigit)
remainder = product % 11;
This produces 5;
subtracting 11 (our mod number) with the remainder gives us 6.
6 being our check digit.
if(string[4] != checkdigit){
return false;
}
or if(string[4] != checkdigit)
return false;
I should have clarified what it was I was trying to achieve.
For all intent purposes when I debug the function
CheckDigitForCustomerCode( char* string )

the product variable contains 60;
the remainder variable contains 5;
the checkdigit variable contains 6;

But the thing is, is that when I go to execute the program my valid
customer code of 24686, comes up as invalid.
I would like to know what could possibly cause this to happen.
string1 is of type integer. string is of type char.
If this or my post is frustrating any members of the newsgroup please
feel reassured that it isn't frustrating you half as much as it is me.

p.s. why I use an empty control statement because my compiler is
logging this as an error or warning when I compile the program without
it, hence the need for an empty control statement.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

passing a parameter 2
inialisation problem. 2
function error 6
Access violation error 10
The program/ header file contents 2
Reading a file 1
Reading a file. 3
strange problem with const char * 2

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top