Thread: Beginners C Programming Challenge

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    12

    Beginners C Programming Challenge

    I've been working on the 2nd Beginners (Help-Free)Programming Challenge of this very same site, and could use some help completing. I have adapted a snippet (by jon guthrie) for a program to permutate a user inputted string.
    Thanks for the help. UC

    Code:
    /*
    **  PERMUTE.C - prints all permutations of an input string
    **
    **  adapted from public domain demo by Jon Guthrie for J. Uslander (4/1/2008).
    **
    */
    
    #include    <string.h>
    #include    <stdlib.h>
    #include    <stdio.h>
    
    int     charcmp(char *, char *);
    
    void    permute(char *, int, int);
    
    char *string;
    
    int     main(void)
    {
        printf("Enter a single word string, using only letters and no spaces.\n");
        fgets(string, 15, stdin);
          int length;
          length = strlen(string);
          if (length != 0 && length <=15)
          {      /* It only works if they're printed in order */
    
          qsort(string, length, 1, (int(*)(const void *, const void *))charcmp);
    
          permute(string, 0, length);
    
          return 0;
          }
          else {
              printf("This program only accepts strings of length 1 letter and not more than 14 letters.\n");
              return(0);
    }
    
    
    /*
    **  This function prints all of the permutations of string "array"
    **  (which has length "len") starting at "start."
    */
    
    void    permute(char *array, int start, int len)
    {
          int j;
          char    *s;
    
          if(start < len)
          {
                if(NULL == (s = malloc(len + 1)))	/* Bug fixed by Stephan Wilms	*/
                {
                      printf("\n\nMemory error!!!\a\a\n");
                      abort();
                }
    
                strcpy(s, array);
                for(j=start ; j<len ; ++j)
                {
                      int     temp;
    
                      if((j == start) || (s[j] != s[start]))
                      {     /* For each character that's different    */
                            /* Swap the next first character with...  */
                            /* the current first                      */
                            temp = s[j];
                            s[j] = s[start];
                            s[start] = temp;
                            permute(s, start+1, len);
                      }
                }
                free(s);
          }
          else  puts(array);
    }
    
    
    
    int charcmp(char *a, char *b)
    {
          return(*a - *b);
    }
    I tried to compile using code::blocks and was told there was an error in the charcmp function.

    Thanks again for your help. UC

  2. #2
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by UCnLA View Post
    I've been working on the 2nd Beginners (Help-Free)Programming Challenge of this very same site, and could use some help completing. I have adapted a snippet (by jon guthrie) for a program to permutate a user inputted string.
    Thanks for the help. UC

    Code:
    /*
    
    ......
    char *string;
    
    int     main(void)
    {
        printf("Enter a single word string, using only letters and no spaces.\n");
        fgets(string, 15, stdin);
    I tried to compile using code::blocks and was told there was an error in the charcmp function.

    Thanks again for your help. UC
    shouldn't you allocate memory for string?

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    12

    Problem allocating memory for string.

    I followed your advice, but I still have problems compiling.
    Can I use strlen(string) as the length argument parameter for fgets??
    What else might be the problem here.
    thanks. UC

    Code:
    #include    <stdio.h>
    
    int     charcmp(char *, char *);
    
    void    permute(char *, int, int);
    
    char malloc(sizeof(*string));
    
    int     main(void)
    {
        printf("Enter a single word string, using only letters and no spaces.\n");
        fgets(string, strlen(string), stdin);
        int length = strlen(string);
                if (length != 0 )
          {      /* It only works if they're printed in order */
    
          qsort(string, length, 1, (int(*)(const void *, const void *))charcmp);
    
          permute(string, 0, length);
    
          return 0;
          }
          else {
              printf("This program requires user to input a single word string(non-NULL).\n");
              abort();

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    maybe somebody more experienced than me will (in the case i'm wrong) contradict me, but the usual practice is to declare string as a big enough array (e.g char string[1024] or string[2048]). Then, if you are sure you don't get a bigger input, you can keep using string. About 1 month ago I had still your same problems (now I have other! ) but if it can help, I give you my actual way of reasoning (and, in the case, somebody will also tell me if i'm still wrong):

    When you write
    Code:
    char *string;
    you tell the compiler that string will point to a char. that is, if you imagine the memory space reserved for string as a small rectangle, in this rectangle it will be written the address of another rectangle containing a char.
    your problem is that you don't initialize at all this "rectangle", so the compiler doesn't know where the hell is this char located. And of course it doesn't know anything about its lenght.
    So you have 2 possibilities: write an address of a dinamically allocated memory (using malloc) or let it point simplier to an array (whose name can be seen as well as a rectangle which contains the address of its the first element. This first rectangle containing the 1st char is followed by other N rectangles, where N is the array size. Remember that C uses a "rectangle" to contain a '\0' which means "THE STRING ENDS HERE. SKIP THE FOLLOWING RECTANGLES!"). Of course your pointer may contain also just the address of a single char, but in this case you couldn't deal with strings but just with one char (the same way you do while dealing with int *aPtr).

    Beside this, I can tell you that you make a wrong use of malloc (it seems like if you declare a prototype of a function of yours!), what you could do in this example would be:

    Code:
    string=(char *) malloc (1024);
    but in this case it's easier to use an array (the flexibility given by malloc is that instead than a constant you can pass it a variable so that it allocates just the memory needed for your string. But you have no clues of its lenght before the user inputs it.

    Also this:

    Code:
      fgets(string, strlen(string), stdin);
    sounds wrong due to what i tried to explain above. string points to nothing in your program, how could you get its lenght?

    I hope I helped you a bit, my suggestion is to study and practice as much as you can since it's the only way of learning how to program! bye

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Read the FAQ on using fgets().
    Begin with a fixed sized array, not a char pointer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You must understand that in your program, there is a lot of memory called "virtual memory," that is divided by bytes. Each byte has an address. A pointer is a variable that contains such an address.
    However, your process does not own all this virtual memory. It must request that it be given permission to write or read from a specific address. That is what malloc does (and to an extent, what the stack does).
    Just defining a pointer will give it a garbage address to somewhere you (most likely) do not have read/write permissions.

    Also beware of buffers overruns: http://cpwiki.sf.net/Buffer_overrun
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    12
    Thanks for everyone's help here.
    1)I allocated memory as suggested (yet I was learned on FAQ that malloc is the prefered method to use), and 2) I am now left with an compiler error regarding the comparison function(charcmp) of the qsort function. Any ideas or suggestions? Relevent code to follow.
    Thanks again.
    UC



    1.
    Code:
       char string[1024];
    2.
    Code:
      qsort(string, length, 1, (int(*)(const void *, const void *))charcmp);
    Code:
      int charcmp(char *a, char *b)
    {
          return(*a - *b);
    }

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Post your error message(s) and your OS/Compiler versions.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2008
    Posts
    12

    compiler error messages

    What follows is the error message after compiling using mingw code::blocks.
    Everything looks in order but this.
    Thanks for your help.
    UC

    Code:
    C:\Users\UC\Downloads\New2C\permute2[1].c||In function `main':|
    C:\Users\UC\Downloads\New2C\permute2[1].c|81|error: syntax error at end of input|
    ||=== Build finished: 1 errors, 0 warnings ===|

  10. #10
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by UCnLA View Post
    What follows is the error message after compiling using mingw code::blocks.
    Everything looks in order but this.
    Thanks for your help.
    UC

    Code:
    C:\Users\UC\Downloads\New2C\permute2[1].c||In function `main':|
    C:\Users\UC\Downloads\New2C\permute2[1].c|81|error: syntax error at end of input|
    ||=== Build finished: 1 errors, 0 warnings ===|
    post line 81 then!

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Is the else at the end of main still missing a closing brace?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User
    Join Date
    Mar 2008
    Posts
    12
    Quote Originally Posted by UCnLA View Post
    What follows is the error message after compiling using mingw code::blocks.
    Everything looks in order but this.
    Thanks for your help.
    UC

    Code:
    C:\Users\UC\Downloads\New2C\permute2[1].c||In function `main':|
    C:\Users\UC\Downloads\New2C\permute2[1].c|81|error: syntax error at end of input|
    ||=== Build finished: 1 errors, 0 warnings ===|
    and line 81....
    Code:
    78  int charcmp(char *a, char *b)
    79  {
    80       return(*a - *b);
    81  }

  13. #13
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    That function compiles fine for me without errors or warnings. I think your problem is elsewhere. How are you calling this function?

    Edit: Oh, wait. You're subtracting two characters and yet are returning an int. Maybe that is your problem.
    Last edited by JDGATX; 04-01-2008 at 01:12 PM.

  14. #14
    Registered User
    Join Date
    Mar 2008
    Posts
    12

    Runtime Error

    Actually it was missing the final bracket from main(). It compiles ok now, but there is a runtime error. It asks the user for an input string, but also prints the error message as follows:

    Code:
    ←[2J←[0;0fEnter a single word string, using only letters and no spaces.
    This program requires user to input a single word string(non-NULL).
    
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    
    Process returned 255 (0xFF)   execution time : 6.271 s
    Press any key to continue.

    Thanks for all your help.
    UC

  15. #15
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    Post your entire C file. I'll see what I can come up with.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginners C Programming Challenge
    By UCnLA in forum C Programming
    Replies: 2
    Last Post: 03-18-2008, 12:15 PM
  2. Programming Challenge (for my school)
    By Ezerhorden in forum C++ Programming
    Replies: 2
    Last Post: 01-04-2006, 06:56 AM
  3. for beginner's or anyone interested
    By Iconoklast in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 03-25-2004, 02:45 PM
  4. Requesting a challenge
    By RealityFusion in forum C++ Programming
    Replies: 8
    Last Post: 08-18-2003, 08:24 PM
  5. What is a good beginners' C++ book?
    By GrNxxDaY in forum C++ Programming
    Replies: 1
    Last Post: 07-29-2002, 09:50 AM