Thread: How to account for different number of chars in an array of names

  1. #1
    Registered User
    Join Date
    Oct 2013
    Posts
    24

    How to account for different number of chars in an array of names

    I am trying to make a for loop that will print out chars in an array while using a #define before main. My problem is that each name has a different amount of chars in it. How do you account for that when you are trying to define a size? For example, I am playing around with the numbers and I just put 7 in for size:
    Code:
    #include <stdio.h>
    #define sizeOf 7
    
    
    
    
    
    
    //char personName( char * name[] );
    char printName ( char * name[]);
    
    
    int main()
    {
        static char  * name[] = {"Bob", "Sally", "Patrick"};
        printName (name);
        
        return 0;
        
        
        
    }
    
    
    char printName(char * name[])
    {
        
        for (i = 0; i <= sizeOf - 1 ; i++)
          for (j = 0; j <= sizeOf - 1 ; j++)
            printf("%c", name[i][j]);
          
        
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Read the printf documentation. Specifically the part about the 's' format specifier (i.e. %s).

  3. #3
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    I got that part, just one last question, I am trying to implement a bubble sort to make things look cleaner and my logic is funky somewhere. Any advice on that part?
    Code:
    #include <stdio.h>
    #define sizeOf 4
    
    
    
    
    
    
    
    
    char personName( char * name[] );
    char printName ( char * name[]);
    
    
    int main()
    {
        static char  * name[] = {"Sally", "Patrick", "Bob", "Tavin"};
        printName (name);
        personName(name);
        
        
        
        return 0;
        
        
        
    }
    
    
    char printName(char * name[])
    {
        
        int i;
        
        printf("The names before they are alphabetized are ");
        for ( i = 0; i <= sizeOf - 1; i++)
        printf("%s ", name[i]);
        printf("\n");
          
        
    }
    
    
    char personName(char * name[])
    {
        
        char * temp;
        int i, j ;
        
        for (i = 0; i <=sizeOf - 1; i++)
        
        {
        
            for (j = 0; j <=sizeOf -1; j++)
            
            {
            
                if (name[j] > name[j+1])
                   {
                       temp = name[j];
                       name[j] = name[j+1];
                       name[j] = temp;
                   }
            }
        }
        printf("The names after they are alphabetized are ");
        for ( j = 0; j <= sizeOf - 1; j++)
        printf("%s ", name[j]);
        
        
        
        
    
    
        
    }

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Line #62 should be name[j+1]=temp.

  5. #5
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    I caught that one a few minutes ago, didn't help with the program crashing though =/. My only guess is that when I'm comparing on line 58 i am comparing the whole string instead of the first letter of the string. I've been trying to fix it but nothing has worked so far.
    Last edited by sammythesp3rmy; 12-09-2013 at 09:23 PM.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    For starters, learn to name things properly. Code that is confusing and difficult to read results in more errors than easy to read code, and those errors tend to be more difficult to find and fix. What the code is supposed to do, what it actually does, and what it appears to do end up being three totally different things.

    personName sounds like a variable that should contain, e.g. the name of a person versus your pet gerbil. But it's a function. So does it name a person (i.e. give them a name)? No, it sorts their names. So something like sortNames would be much better.

    Also, sizeof is a keyword in C that has special meaning: it gives the size of the object in bytes. You should never deviate in naming by just the case of something, it's very confusing: sizeof or sizeOf, which one did you really mean to use? Besides, what if you have 2 array? sizeOf1 and sizeOf2? Somthing like NUM_NAMES would be better, as it tells you that value represents the number of names you have. Also note the use of ALL_CAPS. That is convention for macros and constants. You should also use that in the declaration of name:
    Code:
    #define NUM_NAMES 4
    char *names[NUM_NAMES] = {"Sally", ...};
    Also, I'm not sure why you made the list of names static. Perhaps if you could explain your reasoning, I can tell you whether you really need them to be static, or if there is a different type qualifier/specifier you need.

    Lastly, and the crux of your problem: You can't compare strings with >, <, >=, <=, == or !=. You end up just comparing pointer values which has nothing to do with lexicographic order. You must use strcmp().

  7. #7
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    I am not allowed to use strcmp() unfortunately. This is an assignment and we were forbidden to use that. My teacher was talking in class saying we need to just compare the ascii value of the first letter of the names. the sizeOf was just defining the size of the array, which was my mistake making it pretty much the same looking as sizeof. I have also tried switching things such as doing
    Code:
    for (i = 0; i <=SIZEArray- 1; i++)
        
        {
        
            for (j = 0; j <=SIZEArray - 1; j++)
            
            {
            
                if (  * name[j] >   * name[j+1])
                   {
                       temp = name[j];
                       name[j] = name[j+1];
                       name[j+1] = temp;
                   }
            }
        }
    to try to compare the value of the first letter of each name. And also if it helps, what I get when I run the program is a weird symbol with an @ sign, then Bob Patrick Sally. So it's cutting off the last name and then putting it at the front of the list all garbled for some reason.
    Last edited by sammythesp3rmy; 12-09-2013 at 09:47 PM.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Compile with the warning level set to maximum:
    Code:
    $ make foo
    gcc -g -Wall -std=c99 -o foo foo.c
    foo.c: In function āpersonNameā:
    foo.c:44:1: warning: control reaches end of non-void function [-Wreturn-type]
    foo.c: In function āprintNameā:
    foo.c:24:1: warning: control reaches end of non-void function [-Wreturn-type]
    If you need to return a value from a function, then return one. If not, declare it with a return type of void.

    Quote Originally Posted by sammythesp3rmy View Post
    I am not allowed to use strcmp() unfortunately. This is an assignment and we were forbidden to use that. My teacher was talking in class saying we need to just compare the ascii value of the first letter of the names.
    Next time tell us specifics on the assignment up front. It saves us from wasting time giving advice that is good in general but isn't applicable to your assignment.

    Quote Originally Posted by sammythesp3rmy View Post
    the sizeOf was just defining the size of the array, which was my mistake making it pretty much the same looking as sizeof.
    It's not just that it looks like sizeof. It's also that it's very unclear as to what that value actually is. SIZEArray is not much better than sizeOf. It still doesn't describe the value very well, yes, it's the size of some array, but what array? Size in bytes, or number of elements? NUM_NAMES, or something else equally descriptive (if you don't want to use my suggestion) would be much better.

    A function should do one thing and do it well. Thus, sortNames should only sort names, not print anything. You should call printNames again when you're done sorting.
    Quote Originally Posted by sammythesp3rmy View Post
    I have also tried switching things such as doing
    Code:
    for (i = 0; i <=SIZEArray- 1; i++)
        
        {
        
            for (j = 0; j <=SIZEArray - 1; j++)
            
            {
            
                if (  * name[j] >   * name[j+1])
                   {
                       temp = name[j];
                       name[j] = name[j+1];
                       name[j+1] = temp;
                   }
            }
        }
    to try to compare the value of the first letter of each name. And also if it helps, what I get when I run the program is a weird symbol with an @ sign, then Bob Patrick Sally. So it's cutting off the last name and then putting it at the front of the list all garbled for some reason.
    I assume you're referring to putting the * before name[j]? That will work for just the first letter, but presumably you need to access subsequent letters too, to compare entire names. You would need a whole loop to compare, but see my last paragraph for some tips that should make this easier.

    Your for loops are unconventional. The normal way is
    Code:
    for (i = 0; i < NUM_NAMES; i++);
    Note the use of < and the actual size, instead of <= and size-1. They are equivalent, but most programmers just use < size. You should usually have a good reason for breaking a convention as strong as this.

    Also, consider your j loop. If you have an array with 4 elements, valid indexes are 0..3. You j loop will loop for j values of 0..3. But you access names[j + 1]. So if j is 3, j + 1 is 4, which is out of bounds. Accessing arrays out of bounds is undefined behavior meaning anything could happen: garbage output, crashing (like on my system), etc.

    To keep from making the sort function too complicated, I would write a function called my_strcmp, that behaves exactly like strcmp. Then you can just use
    Code:
    if (my_strcmp(names[j], names[j + 1]) < 0)
    in your sort function. It would also allow you to test your string comparison and name array sorting separately. This is called separation of concerns: keeping separate stuff separate. It results in loosely coupled code and is considered good software practice, and it makes your life easier. It's easier to find a sorting bug when you just have to worry about sorting and not comparing -- and vice-versa. This would allow you to test your my_strcmp function separate from sortNames. You could write sortNames to use strcmp, get the sorting working, then you could write and test my_strcmp, and once that is working, you just change the strcmp call to my_strcmp, and you will be done.

  9. #9
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    Thank you very much for the tips. I really do appreciate all the helpful advice. I figured out it was going out of bounds right before you put this message up. Here is my rewritten code. And we only had to compare the very first letter of each name, so yes, that was what I was trying to do. It was the out of bounds thing that was really tripping me up.
    Code:
    #include <stdio.h>
    #define NUM_NAMES 4
    
    
    
    
    
    
    
    
    void sortName (char * name[] );
    void printName ( char * name[]);
    
    
    int main()
    {
    	char * name[] = {"Sally", "Patrick", "Bob", "Tavin"};
    	
    	printf("The names before they are alphabetized are ");
    	printName (name);
    	sortName(name);
    	printf("The names after they are alphabetized are ");
    	printName (name);
    	
    	
    	
    	return 0;
    	
    	
    	
    }
    
    
    void printName(char * name[])
    {
    	
    	int i;
    	
    	
    	for ( i = 0; i < NUM_NAMES; i++)
    	printf("%s ", name[i]);
    	printf("\n");
    	  
    	
    }
    
    
    void sortName(char * name[])
    {
    	
    	char * temp;
    	int i;
    	int j;
    	
    	for (i = 0; i < NUM_NAMES; i++)
    	
    	{
    	
    		for (j = 0; j < NUM_NAMES - 1; j++)
    		
    		{
    		
    			if (  ( name[j][0]) >   ( name[j+1][0]))
    	   		{
    	   			temp = name[j];
    	   			name[j] = name[j+1];
    	   			name[j+1] = temp;
    	   		}
        	}
    	}
    
    
    	
    
    
    	
    }
    Again, thank you very much for the help. Hopefully in the future, I can be as helpful to others as you have been to me.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Finding Number of Chars in String?
    By FlyingIsFun1217 in forum C++ Programming
    Replies: 5
    Last Post: 12-05-2009, 05:48 PM
  2. Replies: 8
    Last Post: 02-22-2009, 05:17 PM
  3. String w/number and chars...
    By diddy02 in forum C Programming
    Replies: 12
    Last Post: 08-15-2002, 07:16 PM
  4. Taking chars into account.
    By kirby1024 in forum C Programming
    Replies: 4
    Last Post: 06-02-2002, 05:29 AM
  5. unknown number of chars
    By Garfield in forum C Programming
    Replies: 16
    Last Post: 10-31-2001, 05:46 AM