0

i would remove the "-" from the ISBN String. But my code dont print me the value out. Where is the fault?

char *ISBN[20];  //example: 3-423-62167-2
*p = ISBN;

strcpy(ISBN, ptr); //Copy from a Buffer
printf("\nISBN Array: %s", ISBN); //This works!

while(*p)
{
    if (isdigit(*p))
    {
        long val = strtol(p, &p, 10);
        printf("%ld\n", val);         //Do not show anything!
    }
    else
    {
        p++;
    }
}
Tommy
  • 15
  • 4

5 Answers5

2

What about:

for (char* p = ISBN; *p != '\0'; p++)
{
    if (isdigit(*p))
    {
        printf("%c", *p);
    }
}

If you want a long: Save the characters in a char[] (instead of printf()) and then, when done, convert that to a long. You could even use your ISBN array to do an in-place convert:

int i = 0;
for (char* p = ISBN; *p != '\0'; p++)
{
    if (isdigit(*p))
    {
        ISBN[i++] = *p;
    }
}

ISBN[i] = '\0';

long isbn = strtol(ISBN, NULL, 10);

BTW, you forgot p++ when is digit() is true.

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
1

The following code works for me:

#include <stdio.h>
#include <string.h>

int main()
{

char *ptr = "3-423-62167-2";
char ISBN[20];  // should be either ISBN[] or char *ISBN for a string
char *p = ISBN; // declared this one here.. else should be p = ISBN

strcpy(ISBN, ptr);
printf("\nISBN Array: %s\n", ISBN);

while(*p)
{
    if (isdigit(*p))
    {
        long val = strtol(p, &p, 10);
        printf("%ld\n", val);
    }
    else
    {
        p++;
    }
}

}

Have marked the corrections in the comments!

th33lf
  • 2,177
  • 11
  • 15
  • Thank you all! The answers are all useful! But how i can safe the new value as long and work with that? – Tommy Jan 20 '14 at 09:22
  • @legends2k: why would that be? "3-423-62167-2" is a null-terminated string hence (*p) is a good enough exit condition.. – th33lf Jan 20 '14 at 10:30
  • This code will extract the numbers separately; if you only want to get rid of the hyphens and convert the combined number into long then the answer from @meaning-matters is the one you want. – th33lf Jan 20 '14 at 11:16
  • 1
    OK, I was wrong about the infinite loop, but you need to also include _ctype.h_ and _stdlib.h_ too. I upvoted you. – legends2k Jan 20 '14 at 11:24
  • @legends2k: agree with that.. gcc didn't warn me though. – th33lf Jan 20 '14 at 11:28
  • @th33lf: It did warn me when I invoked it as `-Wall -pedantic -std=c11`. – legends2k Jan 20 '14 at 11:29
  • @legends2k: yes, i should've used -Wall. am curious what made you suspect it to be wrong? – th33lf Jan 20 '14 at 11:34
  • Having `p++` only inside the `else`, what I missed was the `strtol`. – legends2k Jan 20 '14 at 11:35
0

Assuming p is char * pointer you should update your code to

//-----v no *
  char ISBN[20];  //example: 3-423-62167-2
  p = ISBN;
//^-- no *

keep rest of the code as is.

Rohan
  • 52,392
  • 12
  • 90
  • 87
0

Incorrectly using strtol is unnecessary; the 2nd argument is not an input, but an output i.e. it sets it to the last interpreted character. Above all, why do you want to convert the character to a long and then convert it back again to a character, when all you need is a character to print?

char ISBN[] = "3-423-62167-2";
char *p = ISBN;
while (*p)
{
    if (isdigit(*p))
        printf("%c", *p);
    ++p;
}

EDIT:

To make the whole string into a long:

unsigned long long num = 0;
while (*p)
{
    if (isdigit(*p))
    {
        const char digit = *p - '0';
        num = (num * 10) + digit;
    }
    ++p;
}
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • I need to convert the ISBN String to long without the "-" to work with that in a Modulo Operation. But with your example i only print the String out. How i can do that? – Tommy Jan 20 '14 at 09:42
  • You mean each digit as a `long` or the whole _3423621672_ as `long`? – legends2k Jan 20 '14 at 09:43
  • whole long: 3423621672 – Tommy Jan 20 '14 at 09:45
  • First of all, with a (signed) `long` of 4 bytes you can only represent upto _2147483647_; with an `unsigned long` of 4 bytes you can represent upto _4294967295_. What would you do when the ISBN number is _8-423-62167-2_? – legends2k Jan 20 '14 at 09:56
  • @user3214376: I'd say you should go with `unsigned long long` which is guarenteed to be atleast 64-bits which can represent upto _18446744073709551615_. Updated the answer with the solution but make sure you aren't running in to [the XY problem](http://meta.stackexchange.com/q/66377). – legends2k Jan 20 '14 at 09:58
  • How i can reset the *p to let him do the loop again, after i changed my ISBN String? – Tommy Jan 22 '14 at 01:23
  • Can you please be more specific and clear? I'm unable to understand you. – legends2k Jan 22 '14 at 06:56
0

I think what the OP wants is to convert a string with hyphens to a long integer. This function converts the decimal digits of a string to a long. Hyphens (in any place) are ignored, other characters, including space, lead to a reading error:

/*
 *      Return ISBN as long or -1L on format error
 */
long isbn(const char *str)
{
    long n = 0L;

    if (*str == '\0') return -1L;

    while (*str) {
        if (isdigit(*str)) {
            n = n * 10 + *str - '0';
        } else {
            if (*str != '-') return -1L;
        }
        str++;
    }

    return n;
}

Note that a long has the same size as an int on some machines and may not be wide enough to store a numeric ISBN.

M Oehm
  • 28,726
  • 3
  • 31
  • 42