Strange error

R

Rick

Hi,

Sorry, I couldn't find a better title for this post. Anyway, I got a piece
of C code which only works well if I put a fprintf in it. Here's the code :

unsigned int8 Port_getPortNum( char *port )
{
fprintf(DB9, "port = %s\r\n", port ); // Don't know why
but I need this fprintf?!
if ( port[1] == 'A' )
{
if ( port[2] == 'I' ) return port[3]-48; else // [3] is a
number 1..9
if ( port[2] == 'O' ) return port[3]-38;
}else
if ( port[1] == 'D' )
{
if ( port[2] == 'I' ) return port[3]-42; else
if ( port[2] == 'O' ) return port[3]-36;
}
fprintf(DB9, "ERROR [3] = %c\r\n", port[3] ); // It shouldn't come
this far
return 0;
} // Port_getPortName

The strange thing is, if I remove the first fprintf the result isn't correct
anymore. I test it with another method :

void PORT_EXPORT( char port[4], char *result, int16 *varlen, int16
*reslen )
{
char test;
test = Port_getPortNum(port);
fprintf( DB9, "PORTID= %i\r\n",test );
<...>
Yep, I need to use a char because I can't give up an integer as parameter.
Maybe the result is ok but the printf's or conversions are wrong... But if I
don't remove that fprintf the result seems to be OK. Sometimes I experience
this problem also in other languages (on fast computers with plenty of
RAM).... What's wrong?

For your information, DB9 in the fprintf is a stream towards a rs232, I use
HyperTerminal to read out the results as it comes from a microcontroller.
And the input port parameter is a string like this : "@AI3" which stands
for Analog Input number 3.

Greetings,
Rick
 
D

Dan Pop

In said:
Sorry, I couldn't find a better title for this post. Anyway, I got a piece
of C code which only works well if I put a fprintf in it. Here's the code :

Post a *complete*, but minimal program illustrating your problem,
explaining what is your function returning with and without the
"magic" fprintf call.

Dan
 
D

Dan Pop

In said:
Rick said:
if ( port[1] == 'A' )
{
if ( port[2] == 'I' ) return port[3]-48;

I would write return port[3]-'0';

I would definitely not do that, considering the rest of the function.
48 is a magical constant, just like the other 3 such constants used in
the code.

Dan
 
R

Rick

Thanks for taking time!

Ok, in short : I got a microcontroller (so I can expect strange stuff with
ram, minimal functions etc.) attached with RS232 to HyperTerminal. In It's
EEPROM all kind of stuff is stored. With several commands in HP I can read
or write. That part works
for now but one function for the adressing not. Of course, before start
reading anything I'll have to give a start position.
The function I showed in the previous post is for calculating the start
position for Port data. With port I mean some in- outputs that are attached
to the microcontroller. With one command I can call all the data of such a
port. A port has more than 1 properties (ala object orientated programming)
so the end result has to be a long string with all the data like this
<name>|<ID>|<unit>|<enabled>|<and so on
You can forget about that part, the error lies in the "Port_getPortNum"
function which returns the index of the asked port object. That has to be a
number from 1..14. By looking at the given name it can be calculated.
Everything works... But, only when that fprintf is included. If I remove it
for some reason it won't work. Here's some code. I didn't have the time to
setup a
working program but this might clear up the situation.

const unsigned long PORT_OFFSET = 1024*8;// EEPROM offset
const unsigned long PORT_TYPE_SIZE = 338; // Size of 1 port 'object'
char gv_SR[15]; // Serial command buffer

// This should return the port number, port is given as a string,
// @AI<number> for analog input 1..6
// @DI<number> for analog input 1..4
// @AO<number> for analog output 1..2
// @DO<number> for analog output 1..2
// In total we got 14 ports, numbered 1..14
// If I remove the first fprintf the whole IF stuff get's skipped, meaning
no
// A or D was detected on port[1].
unsigned int8 Port_getPortNum( char *port )
{
fprintf(DB9, "port = %s\r\n", port ); // MAGICAL PRINTF
if ( port[1] == 'A' )
{
if ( port[2] == 'I' ) return port[3]-48; else
if ( port[2] == 'O' ) return port[3]-38;
}else
if ( port[1] == 'D' )
{
if ( port[2] == 'I' ) return port[3]-42; else
if ( port[2] == 'O' ) return port[3]-36;
}
fprintf(DB9, "ERROR [3] = %c\r\n", port[3] );
return 0; // If it reaches this point something is wrong
} // Port_getPortName



// Read data out of EEPROM and put it into one large string.
// But before we're going to read I need to know where to start
// reading. And that's we're the error occurs
// The port parameter is the port name, result is an output buffer
void PORT_EXPORT( char port[5], char *result )
{
unsigned long pos;
unsigned int8 x; // For testing
x = Port_getPortNum(port);

fprintf( DB9, "PORTID = %U\r\n",x ); // print to RS232 stream

pos = PORT_OFFSET + ( (x-1) * PORT_TYPE_SIZE );
< the export functions, read stuff at 'pos'
we just calculated >
}



void someTestFunction()
{
// GV_SR is used to store a serial command, types in
// by hyperterminal. When I hit enter this void gets
// started. Maybe... the port parameter in PORT_EXPORT is a 5
// long string, GV_SR is 15 long. If I type '@AI1' (+ an enter) it will
// take 5. Maybe I'll have to size the parameter up to 15 as well?
char result[200] = "";

PORT_EXPORT( GV_SR, result );
< clear GV_SR for next command >
< print the result >
}


Greetings,
Rick
 
G

Grumble

Dan said:
Grumble said:
I would write return port[3]-'0';

I would definitely not do that, considering the rest of the function.
48 is a magical constant, just like the other 3 such constants used in
the code.

Dan,

Nothing magical about the four constants.

-48 is -'0'
-42 is -'0'+6 (+6 analog input ports)
-38 is -'0'+6+4 (+4 digital input ports)
-36 ia -'0'+6+4+2 (+2 analog output ports)

Apparently, in a single step, the original poster wants to convert
the ASCII representation of a digit to that digit and add an offset
to compute a port number.

Thus, I would use digit-'0'+offset to make the intent clearer.
 
C

CBFalconer

Rick said:
Sorry, I couldn't find a better title for this post. Anyway, I
got a piece of C code which only works well if I put a fprintf
in it. Here's the code :

unsigned int8 Port_getPortNum( char *port )
{
fprintf(DB9, "port = %s\r\n", port ); // Don't know why
but I need this fprintf?!
if ( port[1] == 'A' )
{
if ( port[2] == 'I' ) return port[3]-48; else // [3] is a
number 1..9
if ( port[2] == 'O' ) return port[3]-38;
}else
if ( port[1] == 'D' )
{
if ( port[2] == 'I' ) return port[3]-42; else
if ( port[2] == 'O' ) return port[3]-36;
}
fprintf(DB9, "ERROR [3] = %c\r\n", port[3] ); // It shouldn't come
this far
return 0;
} // Port_getPortName

The strange thing is, if I remove the first fprintf the result
isn't correct anymore. I test it with another method :

Start by formatting it so it can be read and using real comments:

unsigned int8 Port_getPortNum(char *port)
{
fprintf(DB9, "port = %s\r\n", port );
/* port[3] assumed between '1' and '9' */
if (port[1] == 'A') {
if (port[2] == 'I') return port[3]-'0';
else if (port[2] == 'O') return port[3]-'0' + 10;
}
else if (port[1] == 'D') {
if (port[2] == 'I') return port[3]-'0' + 6;
else if (port[2] == 'O') return port[3]-'0' + 12;
}
/* shouldn't get here */
fprintf(DB9, "ERROR [3] = %c\r\n", port[3] );
return 0;
} /* Port_getPortName */

Now there are some obvious overlaps in possible returned values.
You obviously need some defines and #includes in addition. The
range of port[3] is never tested.

The remainder of your post is off-topic, because it deals with
non-standard C.
 

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

Members online

No members online now.

Forum statistics

Threads
474,109
Messages
2,570,671
Members
47,263
Latest member
SyreetaGru

Latest Threads

Top