Why this doesn't work

Discussion in 'C Programming' started by Milutin_Popovski, Dec 31, 2010.

  1. //It occures is a number palindrom,
    //For example 1221 is plandrom, and 1231 is not...

    #include<stdio.h>
    #include<malloc.h>

    struct lista{
    int val;
    struct lista *next;
    struct lista *prev;
    };

    int main(int argc , char *argv[]){
    int i,j, k, n, m;
    struct lista *first, *temp, *temp_prev, *old, *last;
    if(argc!=2 || !chk(argv[1])){
    printf("\nWrong argument");
    return 1;
    }
    m=atoi(argv[1]);
    first=malloc(sizeof(struct lista));
    temp=first;
    old=first;
    temp->next=NULL;
    temp->prev=NULL;
    old->prev=NULL;
    n=m;
    while(m>0){
    temp->val=m%10;
    old=temp;
    temp->next=malloc(sizeof(struct lista));
    temp=temp->next;
    temp->next=NULL;
    temp->prev=old;
    m=m/10;
    }
    temp=first;
    printf("\n======================\n");
    while(temp->next){
    printf("%d ", temp->val);
    temp=temp->next;
    }
    temp=temp->prev;
    last=temp;
    printf("\n======================\n");
    while(temp){
    printf("%d ", temp->val);
    temp=temp->prev;
    }
    temp=first;
    temp_prev=last;
    while(temp){
    if(temp->val!=temp_prev->val) goto izlaz;
    printf("\n<%d><%d>", temp->val, temp_prev->val);
    temp=temp->next;
    temp_prev=temp_prev->prev;
    }
    printf("\n%d is palindrom", n);
    return 0;
    izlaz:
    printf("\n%d is not a palindrom", n);

    return 0;
    }



    int chk(char *c){
    if(!isdigit(*c) && *c!='\0') return 0;
    if(*c=='\0') return 1;
    *c++;
    chk(c);
    }
     
    Milutin_Popovski, Dec 31, 2010
    #1
    1. Advertising

  2. On Dec 31, 3:41 am, Milutin_Popovski <>
    wrote:
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...
    >

    [...]
    > int main(int argc , char *argv[]){
    >    int i,j, k, n, m;
    >    struct lista *first, *temp, *temp_prev, *old, *last;
    >    if(argc!=2 || !chk(argv[1])){
    >       printf("\nWrong argument");
    >       return 1;
    >    }

    [...]
    > int chk(char *c){
    >    if(!isdigit(*c) && *c!='\0') return 0;
    >    if(*c=='\0') return 1;
    >    *c++;
    >    chk(c);
    >
    > }


    This is as far as I read. Is chk() supposed to
    check that the char array contains all digits?
    if not isdigit *c and *c is not nul?
    The more I look at it, the less it makes sense..
    How about something like ... [OTOH]

    int chk(char *c){
    do {
    if (!isdigit(*c)) return 0;
    } while(*c++);
    return 1;
    }
     
    luser- -droog, Dec 31, 2010
    #2
    1. Advertising

  3. On Dec 31, 4:12 am, luser- -droog <> wrote:

    > int chk(char *c){
    >     do {
    >         if (!isdigit(*c)) return 0;
    >     } while(*c++);

    make that: *++c
    >     return 1;
    >
    > }
    >
    >
     
    luser- -droog, Dec 31, 2010
    #3
  4. On 2010-12-31 10:41, Milutin_Popovski wrote:
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...


    As a first step I would fix the code so that it compiles without warnings.

    $ gcc -Wall -Wextra -ansi -pedantic test.c
    test.c: In function ‘main’:
    test.c:13: warning: implicit declaration of function ‘chk’
    test.c:17: warning: implicit declaration of function ‘atoi’
    test.c:11: warning: unused variable ‘k’
    test.c:11: warning: unused variable ‘j’
    test.c:11: warning: unused variable ‘i’
    test.c: In function ‘chk’:
    test.c:66: warning: implicit declaration of function ‘isdigit’
    test.c:68: warning: value computed is not used
    test.c:70: warning: control reaches end of non-void function


    /August

    --
    The competent programmer is fully aware of the limited size of his own
    skull. He therefore approaches his task with full humility, and avoids
    clever tricks like the plague. --Edsger Dijkstra
     
    August Karlstrom, Dec 31, 2010
    #4
  5. Milutin_Popovski

    Ike Naar Guest

    On 2010-12-31, Milutin_Popovski <> wrote:
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...


    If you write 1231 in base 11 notation, it becomes a1a which _is_ a palindrome.
     
    Ike Naar, Dec 31, 2010
    #5
  6. On 31.12.2010 10:41, Milutin_Popovski wrote:
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...
    >
    > #include<stdio.h>
    > #include<malloc.h>
    >
    > struct lista{
    > int val;
    > struct lista *next;
    > struct lista *prev;
    > };
    >
    > int main(int argc , char *argv[]){
    > int i,j, k, n, m;
    > struct lista *first, *temp, *temp_prev, *old, *last;
    > if(argc!=2 || !chk(argv[1])){
    > printf("\nWrong argument");
    > return 1;
    > }
    > m=atoi(argv[1]);
    > first=malloc(sizeof(struct lista));
    > temp=first;
    > old=first;
    > temp->next=NULL;
    > temp->prev=NULL;
    > old->prev=NULL;
    > n=m;
    > while(m>0){
    > temp->val=m%10;
    > old=temp;
    > temp->next=malloc(sizeof(struct lista));
    > temp=temp->next;
    > temp->next=NULL;
    > temp->prev=old;
    > m=m/10;
    > }


    Now you have allocated one "struct lista" too many, the last
    one being empty.

    > temp=first;
    > printf("\n======================\n");
    > while(temp->next){
    > printf("%d ", temp->val);
    > temp=temp->next;
    > }
    > temp=temp->prev;
    > last=temp;


    This "last" struct lista contains the last digit, but it also
    has a successor, namely the empty one that has been allocated
    above.

    > printf("\n======================\n");
    > while(temp){
    > printf("%d ", temp->val);
    > temp=temp->prev;
    > }
    > temp=first;
    > temp_prev=last;


    The following loop iterates to the empty, "really last" list
    element, but then temp_prev is NULL and the program crashes
    while evaluating temp_prev->val.

    > while(temp){
    > if(temp->val!=temp_prev->val) goto izlaz;
    > printf("\n<%d><%d>", temp->val, temp_prev->val);
    > temp=temp->next;
    > temp_prev=temp_prev->prev;
    > }


    [... the rest snipped ...]


    One fix would be to cleanup the initialisation phase, so that it
    allocates only as many list elements as really required. A second,
    rather quick and dirty repair would be to replace the while(temp)
    condition by while(temp->next).

    The code contains more issues, such as missing error handling in the
    cases where the malloc() operations fail, or failing to free() the
    allocated memory portions when they are not needed anymore.

    -Uli
     
    Ulrich Bellgardt, Dec 31, 2010
    #6
  7. Milutin_Popovski

    Ike Naar Guest

    On 2010-12-31, Milutin_Popovski <> wrote:
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...
    > [code snipped]


    Hint: you can check if an integer is a palindrome without converting
    it to a string representation (so, working with integers only).
    This may lead to a program that is much simpler than what you wrote.
     
    Ike Naar, Dec 31, 2010
    #7
  8. Milutin_Popovski

    BartC Guest

    "Milutin_Popovski" <> wrote in message
    news:...
    > //It occures is a number palindrom,
    > //For example 1221 is plandrom, and 1231 is not...
    >
    > #include<stdio.h>
    > #include<malloc.h>
    >
    > struct lista{
    > int val;
    > struct lista *next;
    > struct lista *prev;
    > };
    >
    > int main(int argc , char *argv[]){
    > int i,j, k, n, m;
    > struct lista *first, *temp, *temp_prev, *old, *last;


    I'm pretty sure you don't need linked lists to find out if an int value is a
    palindrome when represented as a decimal.

    Use a different method, and it might be easier to debug.

    > m=atoi(argv[1]);


    (And if the number starts off as a string anyway, you might as well keep it
    as one. That's then even easier. And means that 01210 will be palindromic,
    but 1210 won't be after converting to a number)

    --
    Bartc
     
    BartC, Dec 31, 2010
    #8
  9. Milutin_Popovski

    Ben Pfaff Guest

    (Richard Harter) writes:

    > Are there any numbers that are not palindromes in any base,
    > with the proviso that the palindrome must have at least two
    > "digits"? If so, which is the smallest?


    I think that 2 is the smallest, because it is not a palindrome in
    base 2, and with bases higher than 2 it has only one digit.
    --
    "Some programming practices beg for errors;
    this one is like calling an 800 number
    and having errors delivered to your door."
    --Steve McConnell
     
    Ben Pfaff, Dec 31, 2010
    #9
  10. Milutin_Popovski

    James Waldby Guest

    On Fri, 31 Dec 2010 10:15:27 -0800, Ben Pfaff wrote:
    > (Richard Harter) writes:
    >
    >> Are there any numbers that are not palindromes in any base, with the
    >> proviso that the palindrome must have at least two "digits"? If so,
    >> which is the smallest?

    >
    > I think that 2 is the smallest, because it is not a palindrome in base
    > 2, and with bases higher than 2 it has only one digit.


    But 2 is a palindrome in base 1. Indeed, every number n>1 is
    a palindrome in base 1 and in base n-1, so if n>1, n is not a
    number that is not a palindrome in any base. However, no number
    that is preceded by a minus sign is a palindrome in a
    number system with a positive base.

    --
    jiw
     
    James Waldby, Dec 31, 2010
    #10
  11. Milutin_Popovski

    Nick Guest

    James Waldby <> writes:

    > On Fri, 31 Dec 2010 10:15:27 -0800, Ben Pfaff wrote:
    >> (Richard Harter) writes:
    >>
    >>> Are there any numbers that are not palindromes in any base, with the
    >>> proviso that the palindrome must have at least two "digits"? If so,
    >>> which is the smallest?

    >>
    >> I think that 2 is the smallest, because it is not a palindrome in base
    >> 2, and with bases higher than 2 it has only one digit.

    >
    > But 2 is a palindrome in base 1. Indeed, every number n>1 is
    > a palindrome in base 1 and in base n-1, so if n>1, n is not a
    > number that is not a palindrome in any base. However, no number
    > that is preceded by a minus sign is a palindrome in a
    > number system with a positive base.


    But base 1 doesn't really exist, at least not in the way the others do,
    because there's no place value. For example, you can't - as far as I
    can see - take a generic multiplication algorithm that works in base 2
    to base something-very-large and use it on base 1 numbers.
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
     
    Nick, Dec 31, 2010
    #11
  12. (Richard Harter) writes:
    > On Fri, 31 Dec 2010 11:07:04 +0000 (UTC), Ike Naar
    > <> wrote:
    >
    >>On 2010-12-31, Milutin_Popovski <> wrote:
    >>> //It occures is a number palindrom,
    >>> //For example 1221 is plandrom, and 1231 is not...

    >>
    >>If you write 1231 in base 11 notation, it becomes a1a which _is_
    >>a palindrome.

    >
    > Which suggests a little puzzle. Are there any numbers that are not
    > palindromes in any base, with the proviso that the palindrome must
    > have at least two "digits"? If so, which is the smallest?


    Yes. 0 is the smallest.

    Given your conditions, neither 1 nor 2 can be expressed as a
    palindrome with at least two digits. Any number N > 2 can be
    expressed as 11 base N-1. (Base 1 doesn't work with the usual
    positional notation; if you relax the rules, 2 can be expressed as
    11 base 1.)

    But I think there's a non-trivial puzzle hiding in there if you
    restrict the possibilities to sufficiently large numbers and
    disallow 11.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 31, 2010
    #12
  13. Milutin_Popovski

    Ben Pfaff Guest

    (Richard Harter) writes:

    > On Fri, 31 Dec 2010 10:15:27 -0800, (Ben Pfaff)
    > wrote:
    >
    >> (Richard Harter) writes:
    >>
    >>> Are there any numbers that are not palindromes in any base,
    >>> with the proviso that the palindrome must have at least two
    >>> "digits"? If so, which is the smallest?

    >>
    >>I think that 2 is the smallest, because it is not a palindrome in
    >>base 2, and with bases higher than 2 it has only one digit.

    >
    > Well done. Is it the only one?


    No. This argument can be generalized: N is not a palindrome in
    base N, and in bases greater than N it has only one digit.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Dec 31, 2010
    #13
  14. On Fri, 31 Dec 2010 02:16:55 -0800 (PST), luser- -droog
    <> wrote:

    >On Dec 31, 4:12 am, luser- -droog <> wrote:
    >
    >> int chk(char *c){
    >>     do {
    >>         if (!isdigit(*c)) return 0;
    >>     } while(*c++);

    > make that: *++c


    While the update is slightly more efficient, it has no practical
    difference from the original.

    >>     return 1;
    >>
    >> }
    >>
    >>


    --
    Remove del for email
     
    Barry Schwarz, Jan 1, 2011
    #14
  15. On Fri, 31 Dec 2010 01:41:07 -0800 (PST), Milutin_Popovski
    <> wrote:

    It would be nice if you told us why you think it is not working.

    >//It occures is a number palindrom,
    >//For example 1221 is plandrom, and 1231 is not...
    >
    >#include<stdio.h>
    >#include<malloc.h>
    >
    >struct lista{
    > int val;
    > struct lista *next;
    > struct lista *prev;
    >};
    >
    >int main(int argc , char *argv[]){
    > int i,j, k, n, m;
    > struct lista *first, *temp, *temp_prev, *old, *last;
    > if(argc!=2 || !chk(argv[1])){
    > printf("\nWrong argument");
    > return 1;
    > }
    > m=atoi(argv[1]);
    > first=malloc(sizeof(struct lista));
    > temp=first;
    > old=first;
    > temp->next=NULL;
    > temp->prev=NULL;
    > old->prev=NULL;


    How many times do you need to set the same object to NULL?

    > n=m;
    > while(m>0){
    > temp->val=m%10;
    > old=temp;
    > temp->next=malloc(sizeof(struct lista));
    > temp=temp->next;
    > temp->next=NULL;
    > temp->prev=old;
    > m=m/10;
    > }
    > temp=first;
    > printf("\n======================\n");
    > while(temp->next){
    > printf("%d ", temp->val);
    > temp=temp->next;
    > }
    > temp=temp->prev;
    > last=temp;
    > printf("\n======================\n");
    > while(temp){
    > printf("%d ", temp->val);
    > temp=temp->prev;
    > }
    > temp=first;
    > temp_prev=last;
    > while(temp){
    > if(temp->val!=temp_prev->val) goto izlaz;


    There is an "else" construct in the language which eliminates the need
    for an unstructured goto like this.

    > printf("\n<%d><%d>", temp->val, temp_prev->val);
    > temp=temp->next;
    > temp_prev=temp_prev->prev;
    > }
    > printf("\n%d is palindrom", n);
    > return 0;
    >izlaz:
    > printf("\n%d is not a palindrom", n);
    >
    > return 0;
    >}
    >
    >
    >
    >int chk(char *c){
    > if(!isdigit(*c) && *c!='\0') return 0;
    > if(*c=='\0') return 1;
    > *c++;


    Why are you bothering to dereference the pointer and then throw the
    resulting char away?

    > chk(c);


    You call the function recursively yet you ignore the value it returns.
    What value will get passed back to main if the first character is a
    valid digit?

    >}


    --
    Remove del for email
     
    Barry Schwarz, Jan 1, 2011
    #15
  16. Milutin_Popovski

    Thad Smith Guest

    On 12/31/2010 1:10 PM, Ben Pfaff wrote:
    > (Richard Harter) writes:
    >
    >> On Fri, 31 Dec 2010 10:15:27 -0800, (Ben Pfaff)
    >> wrote:
    >>
    >>> (Richard Harter) writes:
    >>>
    >>>> Are there any numbers that are not palindromes in any base,
    >>>> with the proviso that the palindrome must have at least two
    >>>> "digits"? If so, which is the smallest?
    >>>
    >>> I think that 2 is the smallest, because it is not a palindrome in
    >>> base 2, and with bases higher than 2 it has only one digit.

    >>
    >> Well done. Is it the only one?

    >
    > No. This argument can be generalized: N is not a palindrome in
    > base N, and in bases greater than N it has only one digit.


    Yes. For integers greater than two, N is a palindrome in base (N-1).

    --
    Thad
     
    Thad Smith, Jan 1, 2011
    #16
  17. On Dec 31, 10:53 pm, Barry Schwarz <> wrote:
    > On Fri, 31 Dec 2010 02:16:55 -0800 (PST), luser- -droog
    >
    > <> wrote:
    > >On Dec 31, 4:12 am, luser- -droog <> wrote:

    >
    > >> int chk(char *c){
    > >> do {
    > >> if (!isdigit(*c)) return 0;
    > >> } while(*c++);

    > >   make that: *++c

    >
    > While the update is slightly more efficient, it has no practical
    > difference from the original.
    >
    > >> return 1;


    Um, I think it does. I think it's crucial, in fact.
    Consider chk("5");
    !isdigit('5') : 0
    *c++ : 1
    !isdigit('\0') : 1
    return 0

    If you don't increment BEFORE dereferencing, you're
    not checking the same value that the next iteration
    will encounter.
     
    luser- -droog, Jan 1, 2011
    #17
  18. Milutin_Popovski

    Ben Pfaff Guest

    Thad Smith <> writes:

    > On 12/31/2010 1:10 PM, Ben Pfaff wrote:
    >> (Richard Harter) writes:
    >>
    >>> On Fri, 31 Dec 2010 10:15:27 -0800, (Ben Pfaff)
    >>> wrote:
    >>>
    >>>> (Richard Harter) writes:
    >>>>
    >>>>> Are there any numbers that are not palindromes in any base,
    >>>>> with the proviso that the palindrome must have at least two
    >>>>> "digits"? If so, which is the smallest?
    >>>>
    >>>> I think that 2 is the smallest, because it is not a palindrome in
    >>>> base 2, and with bases higher than 2 it has only one digit.
    >>>
    >>> Well done. Is it the only one?

    >>
    >> No. This argument can be generalized: N is not a palindrome in
    >> base N, and in bases greater than N it has only one digit.

    >
    > Yes. For integers greater than two, N is a palindrome in base (N-1).


    Oops. Thanks, you're right of course.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Jan 1, 2011
    #18
  19. On Fri, 31 Dec 2010 21:32:18 -0800 (PST), luser- -droog
    <> wrote:

    >On Dec 31, 10:53 pm, Barry Schwarz <> wrote:
    >> On Fri, 31 Dec 2010 02:16:55 -0800 (PST), luser- -droog
    >>
    >> <> wrote:
    >> >On Dec 31, 4:12 am, luser- -droog <> wrote:

    >>
    >> >> int chk(char *c){
    >> >> do {
    >> >> if (!isdigit(*c)) return 0;
    >> >> } while(*c++);
    >> >   make that: *++c

    >>
    >> While the update is slightly more efficient, it has no practical
    >> difference from the original.
    >>
    >> >> return 1;

    >
    >Um, I think it does. I think it's crucial, in fact.
    >Consider chk("5");
    >!isdigit('5') : 0
    >*c++ : 1
    >!isdigit('\0') : 1
    > return 0
    >
    >If you don't increment BEFORE dereferencing, you're
    >not checking the same value that the next iteration
    >will encounter.


    You are correct. My mistake. Sorry.

    --
    Remove del for email
     
    Barry Schwarz, Jan 1, 2011
    #19
  20. On Jan 1, 10:51 am, Barry Schwarz <> wrote:
    > On Fri, 31 Dec 2010 21:32:18 -0800 (PST), luser- -droog
    >
    >
    >
    > <> wrote:
    > >On Dec 31, 10:53 pm, Barry Schwarz <> wrote:
    > >> On Fri, 31 Dec 2010 02:16:55 -0800 (PST), luser- -droog

    >
    > >> <> wrote:
    > >> >On Dec 31, 4:12 am, luser- -droog <> wrote:

    >
    > >> >> int chk(char *c){
    > >> >> do {
    > >> >> if (!isdigit(*c)) return 0;
    > >> >> } while(*c++);
    > >> > make that: *++c

    >
    > >> While the update is slightly more efficient, it has no practical
    > >> difference from the original.

    >
    > >> >> return 1;

    >
    > >Um, I think it does. I think it's crucial, in fact.
    > >Consider chk("5");
    > >!isdigit('5') : 0
    > >*c++          : 1
    > >!isdigit('\0') : 1
    > >    return 0

    >
    > >If you don't increment BEFORE dereferencing, you're
    > >not checking the same value that the next iteration
    > >will encounter.

    >
    > You are correct.  My mistake.  Sorry.
    >


    No sweat. There's something about 'do if' that's easy
    to misinterpret. I suggested something similar about
    a year ago; and someone said it wasn't C.
     
    luser- -droog, Jan 1, 2011
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Prowak

    Why oh why doesn't my data view work?

    David Prowak, Jan 30, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    734
    Alvin Bruney [MVP]
    Jan 30, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    902
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,963
    Smokey Grindel
    Dec 2, 2006
  4. Sara
    Replies:
    6
    Views:
    258
    John W. Krahn
    Apr 12, 2004
  5. PerlFAQ Server
    Replies:
    0
    Views:
    262
    PerlFAQ Server
    Apr 26, 2011
Loading...

Share This Page