Comparing char* with integers and characters

N

Nicholas

How can I compare char* with integers and characters contained in the str,
where integers can be one digit or more?

void Access(char *str) {

char *pt = str;

while (pt != '0') {
if (isalpha(*pt))
printf("A character is found\n");
else if (*pt == '=')
printf("Equal sign is found\n");

// This is the problem
--1) else if (isdigit(*pt))
printf("Only a single digit is accesed usin char*\n"); // It
wont work if the integer is 24, it is only
// accessing '2'
etc. etc.

How can I improve this code to access integers not limited only to 1 digit,
say for an example,
the string is separated by mixed of commas, colons and perios.

example of char *str = "24,5:300.123;

Thank you for the advice
 
I

Ivan Vecerina

....
| // This is the problem
| --1) else if (isdigit(*pt))
| printf("Only a single digit is accesed usin char*\n"); // It
| wont work if the integer is 24, it is only
| // accessing '2'
| etc. etc.
|
| How can I improve this code to access integers not limited only to 1
digit,

Well, it depends what you mean by "access" ...
One thing you can start with is:
else if (isdigit(*pt)) {
char* numBegin = pt;
do { ++pt; } while( isdigit(*pt) );
/* now [numBegin..pt[ is the char range containing a number */

Now to pass the number-string to most C functions, you will need to
zero-terminate it. This can be done by either:
- copying the source string to a local buffer:
char buf[32] = {0};

//NB: need to check for overflow here -- here's a simple way
int len = pt-numBegin;
if( len>=sizeof(buf) ) len = sizeof(buf)-1;

memcpy( buf, numBegin, len );
printf("The number is %s",buf);

- setting a zero-termination in-place (only works if the input
string is modifiable -- Will FAIL if the parameter is a string
literal):
char saved = *pt;
*pt = '\0';
printf("The number is %s",numBegin);
*pt = saved;


hth - Ivan
 
T

Ted

Ivan Vecerina said:
...
| // This is the problem
| --1) else if (isdigit(*pt))
| printf("Only a single digit is accesed usin char*\n"); // It
| wont work if the integer is 24, it is only
| // accessing '2'
| etc. etc.
|
| How can I improve this code to access integers not limited only to 1
digit,

Well, it depends what you mean by "access" ...
One thing you can start with is:
else if (isdigit(*pt)) {
char* numBegin = pt;
do { ++pt; } while( isdigit(*pt) );
/* now [numBegin..pt[ is the char range containing a number */

Thanks Ivan for the reply.

"Access" means that if char str[] = "24,5:300.123"; inside the funtion, I
would like to treat the integers as a group as you mentioned
in the char* numBegin, I'd like to process the 'token': 24 or 300 or 123,
but not 2 or 4 or 5 etc etc...which is satisfied by the numBegin above.

Now to pass the number-string to most C functions, you will need to
zero-terminate it. This can be done by either:
- copying the source string to a local buffer:
char buf[32] = {0};

What do you mean by "to pass the number-string to most C functions"?

If I have this function, say: void Func1(char *str1) and call the function
as Func(numBegin) will give me error ?
Is it because char* numBegin contains "24". What if char* numBegin is only
"5" ?

Can I just use strcpy to numBegin?

Thank you
 
P

Pieter Droogendijk

How can I compare char* with integers and characters contained in the str,
where integers can be one digit or more?

void Access(char *str) {

char *pt = str;

while (pt != '0') {

while an address doesn't equal the value of the character '0'?
I hope you want while (*pt != 0) or (*pt != '\0) or (*pt), which all mean 'while
the character pt points to is not zero'.
if (isalpha(*pt))
printf("A character is found\n");
else if (*pt == '=')
printf("Equal sign is found\n");

// This is the problem

C++ style comments
--1) else if (isdigit(*pt))
printf("Only a single digit is accesed usin char*\n"); // It
wont work if the integer is 24, it is only
// accessing '2'
etc. etc.

How can I improve this code to access integers not limited only to 1 digit,
say for an example,
the string is separated by mixed of commas, colons and perios.

example of char *str = "24,5:300.123;

Look at this:



-
char*x(c,k,s)char*k,*s;{if(!k)return*s-36?x(0,0,s+1):s;if(s)if(*s)c=10+(c?(x(
c,k,0),x(c,k+=*s-c,s+1),*k):(x(*s,k,s+1),0));else c=10;printf(&x(~0,0,k)[c-~-
c+"1"[~c<-c]],c);}main(){x(0,"^[kXc6]dn_eaoh$%c","-34*1'.+(,03#;+,)/'///*");}
 
P

Pieter Droogendijk

Look at this:

Sorry, case of premature sendbuttonclicking;

#include <ctype.h>
#include <stdio.h>

int main ()
{
char *pt = "102,20:hop,5220=gekke pop 5002:";
char numbuf[25];
int i;
for (i=0; *pt; pt++) {
if (isdigit (*pt)) {
/* store digit and increment index variable. */
numbuf = *pt;
i++;
}
else { /* not a digit */
if (i) { /* number wasn't finished */
/* terminate&print number (or do whatever else with it), reset index */
numbuf = 0;
puts (numbuf);
i=0;
}
if (*pt == '=') {
puts ("equals sign found");
}
}
}
/*
* the loop cracks when the terminator is found, leaving the last number string
* unfinished;
*/
if (i) {
numbuf = 0;
puts (numbuf);
}
}

Bounds checking is left as an exercise for the user.
 
I

Ivan Vecerina

| .....
| "Access" means that if char str[] = "24,5:300.123"; inside the funtion, I
| would like to treat the integers as a group as you mentioned
| in the char* numBegin, I'd like to process the 'token': 24 or 300 or 123,
| but not 2 or 4 or 5 etc etc...which is satisfied by the numBegin above.

Hi Ted,
The specific way in which you want to use the numeric string does matter.
For example, if only want to extract the value as an integer, the code
I suggested could be replaced with a single line:
else if (isdigit(*pt))
long numValue = strtol(pt,&pt,10);

However, this is not adequate if you want to extract the exact string
(e.g. preserve any leading zeroes).

Even better, if the format of your input string always the same,
you could use a single call to sscanf to extract all integers:
scanf("%d,%d:%d.%d",&i1,&i2,&i3,&i4);

| > Now to pass the number-string to most C functions, you will need to
| > zero-terminate it. This can be done by either:
.....
|
| What do you mean by "to pass the number-string to most C functions"?
|
| If I have this function, say: void Func1(char *str1) and call the function
| as Func(numBegin) will give me error ?
How will the function know where the string ends ?
By convention, in C, strings extend until the first character
that has a value of zero ( not the zero digit ('0'), but
the NUL char ('\0') ).

| Is it because char* numBegin contains "24". What if char* numBegin is only
| "5" ?
|
| Can I just use strcpy to numBegin?
No... because strcpy like many other functions will look for
the final '\0' -- and will copy until the end of your input string.

This is the case of most string-manipulation functions in
the standard library. Exceptions are function that take
a string or block length as an explicit parameter (e.g. memcpy),
and functions such as atol and strtol which stop processing
their input end at the first non-digit character.


hth
 
I

Ivan Vecerina

| > // This is the problem
|
| C++ style comments

and a standard C comment as well, for 4 years already.


The C standard has moved forward, as well as compiler compliance.
Isn't it time, by now, to tolerate the 1-line comment style
in this NG ?


NFR, please.
Nothing personal, I'm just tired of the finger pointing...
Regards, Ivan
 
S

Stephan Wilms

Hi,
"Access" means that if char str[] = "24,5:300.123"; inside the funtion, I
would like to treat the integers as a group as you mentioned
in the char* numBegin, I'd like to process the 'token': 24 or 300 or 123

You might want to look into using the standard C function "strtok()",
which will break a given zero terminated string into tokens for you:

void tokenizer( char *ptr )
{
char *token;
int num;

token = strtok( str, ",:." );
while ( token != NULL )
{
num = atoi( token);
printf( "the token '%s' was converted to the number %d\n", token,
num );
token = strtok( NULL, ",:." );
}
}
What do you mean by "to pass the number-string to most C functions"?

Standard C library functions typically require zero terminated strings
as their argument, for instance "atoi()" or "strcpy()", etc. Your own
loop doe not append a zero termination char to the tokens, which means
that you wont be able to pass them as arguments to functions expecting
a proper zero terminated string. Note that "strtok()", which I used in
my example above, automatically supplies zero termination of all
tokens.

In your own example you would have to replace the separation char with
'\0' if you wanted to pass the token to a functiojn like "atoi()".
If I have this function, say: void Func1(char *str1) and call the function
as Func(numBegin) will give me error ?

Nope, that will not give you any errors as such. Whatever happens
depends on how the function "Func1()" processes "numBegin".
Can I just use strcpy to numBegin?

As explained above this will require a proper zero termination of the
substring that you want to copy. If you count the number of chars that
you want to copy you might use "strncpy()", though.
 
P

Pieter Droogendijk

| > // This is the problem
|
| C++ style comments

and a standard C comment as well, for 4 years already.


The C standard has moved forward, as well as compiler compliance.
Isn't it time, by now, to tolerate the 1-line comment style
in this NG ?

Yes, I suppose it's C99's time now isn't it. Noted for future reference.
It's just that I still see it as C++ (it was rubbed in that way). Hard to shake
I guess...
 
R

Richard Bos

(e-mail address removed) (Stephan Wilms) wrote:

<double take>

Hey, look at who's back! I should go on holidays more often, it gives
welcome old farts a chance to sneak back in behind my back...

Richard
 
I

Irrwahn Grausewitz

Ivan Vecerina said:
| > // This is the problem
|
| C++ style comments

and a standard C comment as well, for 4 years already.

The C standard has moved forward, as well as compiler compliance.
Isn't it time, by now, to tolerate the 1-line comment style
in this NG ?
One problem when posting code with C99-style single-line
comments in usenet is the possible line-wrap that can cause a
lot of confusion eventually, especially when pieces of code
are commented out but accidentely wrap to a new line and get
compiled after cut-and-paste.

Irrwahn
 
M

Martin Ambuhl

Ivan said:
| > // This is the problem
|
| C++ style comments

and a standard C comment as well, for 4 years already.


The C standard has moved forward, as well as compiler compliance.
Isn't it time, by now, to tolerate the 1-line comment style
in this NG ?

No. Within the last day we have seen code posted with '// ...' comments in
lines in the range of 160 characters. In posting code in newsgroups, where
many people have newsreaders set to line-lengths limited to 80 or somewhat
(quite reasonably, unless you really enjoy horizontal scrolling), '// ...'
comments invite broken lines which must be reconstituted.
 
L

LibraryUser

Pieter said:
Yes, I suppose it's C99's time now isn't it. Noted for future
reference. It's just that I still see it as C++ (it was rubbed
in that way). Hard to shake I guess...

No, it isn't time, not in a newsgroup. // comments get line
wrapped and result in errors, while /* */ comments function
correctly.
 
N

Nicholas

Pieter Droogendijk said:
Look at this:

Sorry, case of premature sendbuttonclicking;

#include <ctype.h>
#include <stdio.h>

int main ()
{
char *pt = "102,20:hop,5220=gekke pop 5002:";
char numbuf[25];
int i;
for (i=0; *pt; pt++) {
if (isdigit (*pt)) {
/* store digit and increment index variable. */
numbuf = *pt;
i++;
}
else { /* not a digit */
if (i) { /* number wasn't finished */
/* terminate&print number (or do whatever else with it), reset index */
numbuf = 0;
puts (numbuf);
i=0;
}
if (*pt == '=') {
puts ("equals sign found");
}
}
}
/*
* the loop cracks when the terminator is found, leaving the last number string
* unfinished;
*/
if (i) {
numbuf = 0;
puts (numbuf);
}
}


Thank you for the advice, Pieter. What is the purpose if if (i) here ?
The code has been modified as follows:

At the end of the while loop, I would like to know that the integer values
are two, other symbol is one.
Integers: 3500 and 5
Other symbol: *

char*pt = "3500*5";
char numbuf[30];
int i;
// Counting the other symbols and integers
int others, integers;


Inside the function:

while (*ptr != '\0') {
if (isdigit(*ptr)) {
while (*ptr != '\0') { // Is it alright ?
// Need to 'peek' to the next one before -**- it if is integer
// If it is not integer, reset to the original ptr
numbuf = *pt;
i++;
ptr++;
}
integers++;
}
else // It is another symbol
other++;
ptr++; // -**-
}

printf("Integers: %d\n", integers);
printf("Other symbols: %d\n", others);

Thank you for the comments
Bounds checking is left as an exercise for the user.


--
char*x(c,k,s)char*k,*s;{if(!k)return*s-36?x(0,0,s+1):s;if(s)if(*s)c=10+(c?(x
(
c,k,0),x(c,k+=*s-c,s+1),*k):(x(*s,k,s+1),0));else
c=10;printf(&x(~0,0,k)[c-~-
c+"1"[~c<-c]],c);}main(){x(0,"^[kXc6]dn_eaoh$%c","-34*1'.+(,03#;+,)/'///*");
}
 

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
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top