473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

strtol with hex greater than 4 byte ?

Hi,

I will check a String which should contain a HEX value.
I know that strtol is the right function for this job.

But what happens when I will check a hex string with 8 bytes?
That I can check that the string is correct i know.

long value;
char src[]="0x1234567812345678"
char *err;
value = strtol(src,&err, 16);
if (*err != 0x00)
return -1; /*FEHLER*/

The value is not 0x12345678 but I know it is right spelled.

Is that C89 standard or only on my compiler/OS (VC6, Windows) ?

Is there a way to get the right value of the beginning of the string,
up to the sizeof(long) ?

Thx
Peter
Nov 14 '05 #1
10 5087
Peter Dunker wrote:
Hi,

I will check a String which should contain a HEX value.
I know that strtol is the right function for this job.

But what happens when I will check a hex string with 8 bytes?
That I can check that the string is correct i know.

long value;
char src[]="0x1234567812345678"
char *err;
value = strtol(src,&err, 16);
Note that in this case (string starts with "0x") you could set
base to 0 and let strtol() figure it out. Just a remark; being
explicit is usually a good programming habit. :-)
if (*err != 0x00)
return -1; /*FEHLER*/

The value is not 0x12345678 but I know it is right spelled.

Is that C89 standard or only on my compiler/OS (VC6, Windows) ?
Unless long is 64-bit on your platform (which I assume is not, but
rather 32-bit), strtol() processes the full src[] and overflows.
According to K&R, page 252 LONG_MAX is returned, which is indeed
not equal to 0x12345678. Also errno is set to ERANGE.

Is there a way to get the right value of the beginning of the string,
up to the sizeof(long) ?
Not that I know of, using standard library functions. In that case you
must do it yourself. You could for example make a copy of the string
up to sizeof long bytes and pass that copy to strtol().
Thx
Peter


Nov 14 '05 #2

"Case" <no@no.no> schrieb im Newsbeitrag
news:40*********************@news.xs4all.nl...
Peter Dunker wrote:
Hi,

I will check a String which should contain a HEX value.
I know that strtol is the right function for this job.

But what happens when I will check a hex string with 8 bytes?
That I can check that the string is correct i know.

long value;
char src[]="0x1234567812345678"
char *err;
value = strtol(src,&err, 16);
Note that in this case (string starts with "0x") you could set
base to 0 and let strtol() figure it out. Just a remark; being
explicit is usually a good programming habit. :-)

I know the possibility with 0, but the string should/must be a hex
value, if there is a possibilty to get the used base after strtol is
done, that will be create, but I don't think so.
I have written a big "if" with str[0] and str[1] to check a x X 0x 0X
at the beginning of the string and do then the strtol.
if (*err != 0x00)
return -1; /*FEHLER*/

The value is not 0x12345678 but I know it is right spelled.

Is that C89 standard or only on my compiler/OS (VC6, Windows) ?


Unless long is 64-bit on your platform (which I assume is not, but
rather 32-bit), strtol() processes the full src[] and overflows.
According to K&R, page 252 LONG_MAX is returned, which is indeed
not equal to 0x12345678. Also errno is set to ERANGE.

Thx, that sounds interessting.
Is there a way to get the right value of the beginning of the string, up to the sizeof(long) ?


Not that I know of, using standard library functions. In that case

you must do it yourself. You could for example make a copy of the string
up to sizeof long bytes and pass that copy to strtol().

OK I will do something like this, when I need the value.

Thx
Peter
Nov 14 '05 #3
Peter Dunker wrote:
"Case" <no@no.no> schrieb im Newsbeitrag
news:40*********************@news.xs4all.nl...
Peter Dunker wrote:
Hi,

I will check a String which should contain a HEX value.
I know that strtol is the right function for this job.

But what happens when I will check a hex string with 8 bytes?
That I can check that the string is correct i know.

long value;
char src[]="0x1234567812345678"
char *err;
value = strtol(src,&err, 16);


Note that in this case (string starts with "0x") you could set
base to 0 and let strtol() figure it out. Just a remark; being
explicit is usually a good programming habit. :-)


I know the possibility with 0, but the string should/must be a hex
value, if there is a possibilty to get the used base after strtol is
done, that will be create, but I don't think so.
I have written a big "if" with str[0] and str[1] to check a x X 0x 0X
at the beginning of the string and do then the strtol.


According to K&R x and X do not make the string hexadecimal. Only 0x or
0X are valid. So watch this! ---(What precisely do you want to catch
with this test? I means, is the 0x or 0X the only thing you expect to
go wrong possibly? Does this string come from user input?)---note

Nov 14 '05 #4
> According to K&R x and X do not make the string hexadecimal. Only 0x
or
0X are valid. So watch this! very interessting.

---(What precisely do you want to catch with this test? I means, is the 0x or 0X the only thing you expect to go wrong possibly? Does this string come from user input?)---note

I read a XML Document, and will check that every numbered value is in a
special HEX format. If it is not, the user have to correct the
Document.
The correct Format is needed because I will save some information in my
own data format, and will link to the string(hex) inside the parser
implementation. So I don't need to copy all Data and out of my Program
I know that hex_string[2] up to the the NULL pointer is the hex value
in Bytes. (0x....)

Thx for your hints
Peter
Nov 14 '05 #5
In <c6**********@piggy.rz.tu-ilmenau.de> "Peter Dunker" <Pe**********@stud.tu-ilmenau.de> writes:
I will check a String which should contain a HEX value.
I know that strtol is the right function for this job.

But what happens when I will check a hex string with 8 bytes?
That I can check that the string is correct i know.

long value;
char src[]="0x1234567812345678";
char *err;
value = strtol(src,&err, 16);
if (*err != 0x00)
return -1; /*FEHLER*/

The value is not 0x12345678 but I know it is right spelled.

Is that C89 standard or only on my compiler/OS (VC6, Windows) ?
It is C89, but your test is incorrect, as "0x1234567812345678" is of
the expected form in its entirety and there is no final string, so err
is guaranteed to point to the terminating null character:

fangorn:~/tmp 756> cat test.c
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>

int main()
{
long value;
char src[]="0x1234567812345678";
char *err;

errno = 0;
value = strtol(src, &err, 16);
perror("strtol");
printf("%ld %ld\n", value, LONG_MAX);
printf("%d\n", *err);
return 0;
}
fangorn:~/tmp 757> gcc test.c
fangorn:~/tmp 758> ./a.out
strtol: Numerical result out of range
2147483647 2147483647
0

Which is exactly as documented: value is set to LONG_MAX, errno is set
to ERANGE and err points to the terminating null character. Of course,
the result would be different on a machine with 64-bit long's.

It is a real PITA to perform error checking correctly after a strtol
call:

errno = 0;
value = strtol(src, &err, 16);
if (err == src) /* complete garbage input */ ;
if (*err != 0) /* trailing garbage */ ;
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
/* overflow */;
/* value contains the result of a successful conversion */ ;

Depending on the application, the case of trailing garbage may not be
considered an error.
Is there a way to get the right value of the beginning of the string,
up to the sizeof(long) ?


Yes. The easy way is to insert a null character at the right place in
the input string. The hard way (when it is not guaranteed that the
input string can be modified) is to generate a sscanf format specifying
the maximum number of characters that should be converted and use it in
an sscanf call.

The hardest part is to compute the number of characters without
making *any* assumptions. sizeof(long) * 2 + 2 assumes an 8-bit byte
(and no padding bits). sizeof(long) * CHAR_BIT / 4 + 2 assumes a CHAR_BIT
that is a multiple of 4 and no padding bits in the representation. So,
you really have to start by "dissecting" LONG_MAX... And the easiest
way of doing it is:

char buff[sizeof(long) * CHAR_BIT / 3 + 2];
sprintf(buff, "%lx", (unsigned long)LONG_MAX);

Now, strlen(buff) + 2 is the bullet-proof solution to our problem.

The C99 snprintf removes the need for allocating buff, but reduces the
code portability (the SUS2 version of snprintf is useless for our purpose
and many C89 implementations don't provide snprintf at all).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #6
Dan Pop wrote:
It is a real PITA to perform error checking correctly after a strtol
call:
[...]
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
/* overflow */;


If my reading of the standard is correct, (errno == ERANGE) should
suffice for this error condition (although you'll normally want to
check whether it was too positive or too negative in the following
code), as this `use' of errno is documented; implementations might
set errno to some other non-zero value if there's no overflow, but
ERANGE seems to be reserved. (This reading is likely mere wishful
thinking; it seems far more likely that the intent is to prevent a
different value from being used under circumstances wherein one is
already prescribed.)

--
++acr@,ka"
Nov 14 '05 #7

"Sam Dennis" <sa*@malfunction.screaming.net> schrieb im Newsbeitrag
news:sl****************@ID-227112.user.uni-berlin.de...
Dan Pop wrote:
It is a real PITA to perform error checking correctly after a strtol call:
[...]
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE) /* overflow */;
If my reading of the standard is correct, (errno == ERANGE) should
suffice for this error condition (although you'll normally want to
check whether it was too positive or too negative in the following
code), as this `use' of errno is documented; implementations might
set errno to some other non-zero value if there's no overflow, but
ERANGE seems to be reserved. (This reading is likely mere wishful
thinking; it seems far more likely that the intent is to prevent a
different value from being used under circumstances wherein one is
already prescribed.)


THX

New Question, what is different between the || and | (&& and &)
I read anthing about that but I can't remember.
Is the if also correct if you use the & and | ?
Nov 14 '05 #8
In <sl****************@ID-227112.user.uni-berlin.de> Sam Dennis <sa*@malfunction.screaming.net> writes:
Dan Pop wrote:
It is a real PITA to perform error checking correctly after a strtol
call:
[...]
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
/* overflow */;


If my reading of the standard is correct, (errno == ERANGE) should
suffice for this error condition (although you'll normally want to
check whether it was too positive or too negative in the following
code), as this `use' of errno is documented; implementations might
set errno to some other non-zero value if there's no overflow, but
ERANGE seems to be reserved. (This reading is likely mere wishful
thinking; it seems far more likely that the intent is to prevent a
different value from being used under circumstances wherein one is
already prescribed.)


If strtol is not returning LONG_MAX or LONG_MIN, what is preventing it
from setting errno to ERANGE?

The strtol usage of errno is documented *only* for the cases when
the return value is LONG_MAX or LONG_MIN.

The general rule is to ignore errno unless the function signals an error.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #9
In <c6**********@piggy.rz.tu-ilmenau.de> "Peter Dunker" <Pe**********@stud.tu-ilmenau.de> writes:
New Question, what is different between the || and | (&& and &)
I read anthing about that but I can't remember.
Read again, until you can remember. It's a basic feature of the language.
Actually, it's trivial to remember, once you have *really* understood the
differences between them.
Is the if also correct if you use the & and | ?


In that particular case, yes. However, compare

if (x != 0 && 1.0 / x > FOO) ...

and

if (x != 0 & 1.0 / x > FOO) ...

and try to figure out which is correct and why.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #10
Da*****@cern.ch (Dan Pop) wrote in message news:<c6**********@sunnews.cern.ch>...
In <sl****************@ID-227112.user.uni-berlin.de> Sam Dennis <sa*@malfunction.screaming.net> writes:
Dan Pop wrote:
It is a real PITA to perform error checking correctly after a strtol
call:
[...]
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
/* overflow */;
If my reading of the standard is correct, (errno == ERANGE) should
suffice for this error condition (although you'll normally want to
check whether it was too positive or too negative in the following
code), as this `use' of errno is documented; implementations might
set errno to some other non-zero value if there's no overflow, but
ERANGE seems to be reserved. (This reading is likely mere wishful
thinking; it seems far more likely that the intent is to prevent a
different value from being used under circumstances wherein one is
already prescribed.)


If strtol is not returning LONG_MAX or LONG_MIN, what is preventing it
from setting errno to ERANGE?


7.5p3 ... The value of errno may be set to nonzero by a
library function call whether or not there is an error,
provided the use of errno is not documented in the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
description of the function in this International Standard.
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The strtol usage of errno is documented *only* for the cases when
the return value is LONG_MAX or LONG_MIN.


Hence, errno will only be set in that case.

What am I missing?

--
Peter
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Pavel Krcmar | last post by:
Hi, I'am a little bit confused. I tried this snippet (below) and ( endptr != NULL ) is true everytime. I was looking to http://www.mkssoftware.com/docs/man3/strtol.3.asp and then to...
11
by: nrk | last post by:
Isn't: char s = "--4"; char *endptr; strtol(s, &endptr, 0); supposed to return 0 and set endptr to s? I have run into an implementation (not gcc, gcc does what I expect) that is returning...
3
by: whisper | last post by:
Hello: I am trying to write code to read in a bunch of lines from stdin, each containing a (variable) number of integers and writing each integer in a separate line to stdout. I came up the...
2
by: Marlene Stebbins | last post by:
Suppose I'm using strtol() to convert a command line string to a number and I want to check that the input to strtol() is not non-numeric. strtol() returns zero if input is non-numeric, so I can...
14
by: Kristo | last post by:
Since there's no strtoi function in standard C, I've been searching the clc archives for the proper way to store the result of strtol to an int. My search has yielded conflicting results. About...
3
by: dstevel | last post by:
The signature for strtol is: strtol( const char*, char**, int) So.. if we start with a passed "const char*" (pointer to const char), then we can't create a non-const char pointer pointer to...
77
by: borophyll | last post by:
As I read it, C99 states that a byte is an: "addressable unit of data storage large enough to hold any member of the basic character set of the execution environment" (3.6) and that a byte...
13
by: =?Utf-8?B?YXVsZGg=?= | last post by:
i have come across a situation in my project where i read a text file with some characters greater than hex 0x7f. i need to write character (0xE0) to a new file as an exception. however when i...
8
by: lovecreatesbea... | last post by:
Does this part of C code call and check strtol() correctly? port = strtol(argv, &endptr, 10); if (argv == endptr){ fprintf(stderr, "%s\n", "Invalid port number form"); return 1; } if (port ==...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.