Proofing existing functions

This is a discussion on Proofing existing functions within the C Programming forums, part of the General Programming Boards category; The following program is one I am writing for one of my classes. It is basically a proof of 3 ...

  1. #1
    Registered User
    Join Date
    Feb 2004
    Posts
    73

    Proofing existing functions

    The following program is one I am writing for one of my classes. It is basically a proof of 3 functions in strings.h. The problem I am having is with the toupper loop you see in strcap. The problem is that it is printing nothing at all. The malloc statement is one I have never used before, so I am hoping I am using it correctly. Regardless, the printing of the string is the onnly problem right now. The other function, strcmp, hasn't been written yet, so dont worry about it. Although, with my notes on it so far, I am wondering if an if statement in a loop could be made to check each letter. It seems like it would be really drawn out and complex though.

    Code:
    # include <stdio.h>
    # include <ctype.h>
    # include <stdlib.h>
    
    int strlen (char *s) {       /*finds the length of the array*/
    
      int counter = 1;
      char *p;
    
         for (p=s; *p; p++) {
             counter++;
         }
      return counter;
    }
    
    int strncmp (char *s, char *t, int n) {    /*compares the two arrays*/
    
    }
    
    char *strcap (char *str) {       /*capitalizes all the letters in an array*/
    
      char *result = (char *) malloc (250);
    
         for (result=str; *result; result++) {
             toupper(*result);
         }
      return result;
    }
    
    int main () {
    
    	char *str = "The Gators need to make it past the second round in March";	
    	char *str1 = "The Gators";
    	char *str2 = "The Gators need to make it past the second round in March";
    
    	printf ("\n%s", str);
        printf ("\n%d", strlen (str1));
    	printf ("\n%d", strncmp (str, str1, 20));	
    	printf ("\n%d", strncmp (str, str1, 10));	
    	printf ("\n%d", strncmp (str, str2, strlen (str)));	
    	printf ("\n%s", strcap (str));
        printf ("\n%s\n", str);
    
          system("PAUSE");
          return 0;
    }

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >char *result = (char *) malloc (250);
    All well and good (sort of, but still correct). result now points to the start of a block of memory 250 bytes in size.

    >for (result=str; *result; result++) {
    Not okay. You just lost your memory by assigning str to result. You want something more like this:
    Code:
    char *strcap (char *str) {       /*capitalizes all the letters in an array*/
    
      char *result = malloc (250);
      char *p = result;
    
      while (*str != '\0')
        *p++ = (char)toupper(*str++);
      *p = '\0';
    
      return result;
    }
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Feb 2004
    Posts
    73
    Prelude where would I be without you.

    Question. Why do you need the (char) in front of the toupper statement.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >Prelude where would I be without you.
    Without me you would be in the depths of segfault hell, forced to port VAX/VMS applications to MS-DOS while being whipped with hardcopy of the Windows 3.0 source code by Herbert Schildt.

    >Why do you need the (char) in front of the toupper statement.
    It silences a warning on my favorite compiler. toupper returns an integer and assigning an integer to a character could result in a loss of information, so the compiler is obliged to warn about it. The cast tells the compiler that I'm well aware of the potential danger.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Feb 2004
    Posts
    73
    Ah, ok.

    As for the above mentioned strcmp function, would my method I described be adequete, or I was thinking of somehow translating the characters into their binary cousins (if this step is even necessary), and compare them against the other. I dunno, maybe I am overcomplicating the subject and i can just do a double loop and compare each character individually that way directly.

  6. #6
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    >It silences a warning on my favorite compiler.
    And which compiler would that be?
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >would my method I described be adequete
    You're thinking to hard about it. strncmp is nothing more than a loop terminating when n reaches 0 or the end of the string is found, and a test for equality in the body. Just remember to return -1, 0, or +1 accordingly.
    My best code is written with the delete key.

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >And which compiler would that be?
    Visual C++ .NET. But only because my employers make me...yes, that's it.
    My best code is written with the delete key.

  9. #9
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Microsoft? Ewwwwwwwwwwwwwwwwwwwww.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  10. #10
    Registered User
    Join Date
    Feb 2004
    Posts
    73
    Well I am still working on that strcmp function, but I have made some progress. I am still a little worried about the incrementing both strings at once so they compare the same character number each time. I thought I had it figured out, but I am missing somethhing in terms of the returns I think.

    Code:
    int strncmp (char *s, char *t, int n) {    /*compares the two arrays*/
    
      char *p1, *p2;
    
      for (p1 = s, p2=t; *p1, *p2; p1++, p2++)
      {
          if (*p1 > *p2)
            return 1;
          if (*p1 < *p2)
            return -1;
          if (*p1 == '\0' || *p2 == '\0')
            break;
      }
      return 0;
    }

  11. #11
    Registered User
    Join Date
    Feb 2004
    Posts
    73
    I made a little progress, but there is still a weird error in the results of strcmp.

    Let me show what I have:

    [code]
    # include <stdio.h>
    # include <ctype.h>
    # include <stdlib.h>

    int strlen (char *s) { /*finds the length of the array*/

    int counter = 1;
    char *p;

    for (p=s; *p; p++) {
    counter++;
    }
    return counter;
    }

    int strncmp (char *s, char *t, int n) { /*compares the two arrays*/

    char *p1, *p2;

    for (p1=s, p2=t; n; p1++, p2++)
    {
    if (*p1 > *p2)
    return 1;
    if (*p1 < *p2)
    return -1;
    if (*p1 == '\0' || *p2 == '\0')
    break;
    }
    return 0;
    }

    char *strcap (char *str) { /*capitalizes all the letters in an array*/

    char *result = malloc (250);
    char *p = result;

    while (*str != '\0')
    *p++ = (char)toupper(*str++);
    *p = '\0';

    return result;
    }

    int main () {

    char *str = "The Gators need to make it past the second round in March";
    char *str1 = "The Gators";
    char *str2 = "The Gators need to make it past the second round in March";

    printf ("\n%s", str);
    printf ("\n%d", strlen (str1));
    printf ("\n%d", strncmp (str, str1, 20));
    printf ("\n%d", strncmp (str, str1, 10));
    printf ("\n%d", strncmp (str, str2, strlen (str)));
    printf ("\n%s", strcap (str));
    printf ("\n%s\n", str);

    system("PAUSE");
    return 0;
    }[\code]

    The second number should be 0 instead of 1 because the length of the compare is only a certain number long, and at that point they are equal, but it looks like it is taking into account the rest of the string, which it shouldn't with the given parameters., I dont know what is going on.

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    You don't decrement n:
    Code:
    int strncmp (char *s, char *t, int n) { /*compares the two arrays*/
    
      char *p1, *p2;
    
      for (p1=s, p2=t; n--; p1++, p2++)
      {
        if (*p1 > *p2)
          return 1;
        if (*p1 < *p2)
          return -1;
        if (*p1 == '\0' || *p2 == '\0')
          break;
      }
      return 0;
    }
    My best code is written with the delete key.

  13. #13
    Registered User
    Join Date
    Feb 2004
    Posts
    73
    I would have never gotten that. How does that work? Decrementing n-- in the conditional spot of the for loop.

  14. #14
    C Programmer Stack Overflow's Avatar
    Join Date
    Apr 2004
    Posts
    477

    Post

    Hello all,

    I'm not sure if this helps, but I have written an strncmp() prototype before. It's kinda short and simple, and I believe it works:

    Code:
    int strncmp(const char *string1, const char *string2, size_t num) {
    	int	char1, char2;
    
    	do {
    		char1 = *string1++;
    		char2 = *string2++;
    
    		if (!num--)
    			return 0;
    		
    		if (char1 != char2)
    			return char1 < char2 ? -1 : 1;
    	} while (char1);
    	
    	return 0;
    }
    Code 1.1: strncmp() prototype example

    Also, I'm not sure if you'd want to malloc() 250 bytes everytime you call on strcap() also assuming you already allocated memory for your string before calling on a function. I might be wrong though, but this implementation hasn't crashed on me since:

    Code:
    char *strcap (char *str) {
    	char	*s = str;
    
    	while (*s) {	// while it isnt 0
    		*s = toupper(*s);
    		s++;
    	}
    
    	return str;
    }
    Code 1.2: Converting whole string to uppercase

    If I am wrong in my thinking and function(s), please let me know. I just try to stay away from using any allocation initialization when using a prominent function.


    Hope this helps,
    - Stack Overflow
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >but this implementation hasn't crashed on me since
    You've been lucky. If strcap is called with a string literal as the argument (like in pxleyes' driver) then you could very well have problems. You shouldn't attempt to modify string literals.

    >I'm not sure if you'd want to malloc() 250 bytes everytime you call on strcap()
    I agree that as it is the allocation isn't the best, and decentralizing allocation and release of memory from a single function tends to result in memory leaks. You can ignore the issue of forgetting to free the memory and simply do this:
    Code:
    char *strcap ( const char *str )
    {
      char *rs = malloc ( strlen ( str ) + 1 );
      char *p;
    
      if ( rs == NULL )
        return NULL;
      for ( p = rs; ( *p = *str ) != '\0'; p++, str++ )
        ;
    
      return rs;
    }
    Past that you would need to force restrictions on the caller by requiring a buffer of the appropriate size be passed, or only modifiable strings be allowed. The former is awkward in this case and the latter is impossible to test for. Make your own conclusions.

    >I just try to stay away from using any allocation initialization when using a prominent function.
    It's best to take things on a case by case basis. Different situations will have different advantages and disadvantages. Strictly following a simple guideline of avoiding dynamic memory for prominent functions can get you into trouble just as easily as using dynamic memory poorly.

    >How does that work? Decrementing n-- in the conditional spot of the for loop.
    Work it out on paper, first test then decrement and see how the end result is n iterations of the loop.
    My best code is written with the delete key.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. calling functions within functions
    By edd1986 in forum C Programming
    Replies: 3
    Last Post: 03-29-2005, 03:35 AM
  2. Factory Functions HOWTO
    By GuardianDevil in forum Windows Programming
    Replies: 1
    Last Post: 05-01-2004, 02:41 PM
  3. Shell functions on Win XP
    By geek@02 in forum Windows Programming
    Replies: 6
    Last Post: 04-19-2004, 06:39 AM
  4. Inline functions and inheritance
    By hpy_gilmore8 in forum C++ Programming
    Replies: 3
    Last Post: 01-14-2004, 06:46 PM
  5. functions - please help!!!!
    By linkies in forum C Programming
    Replies: 1
    Last Post: 08-21-2002, 08:53 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21