Thread: Basic Help with Arrays and Output

  1. #1
    Registered User
    Join Date
    Jul 2006
    Posts
    49

    Unhappy Basic Help with Arrays and Output

    Okay, here's a simplified version of my program:

    Code:
    /* INCLUDES */
    #include <stdio.h>
    
    int lookupTable(char dataCharacter1, char dataCharacter2);
    char encodeB(int dataCharacter, int position);
    
    main()
    {
    	int i;
    	int inputB[4];
    	int outputB[120];
    	
    	*outputB = 0;
    
    	/* test sequence 0367 */
    	inputB[0] = 0;
    	inputB[1] = 3;
    	inputB[2] = 6;
    	inputB[3] = 7;
    
    	for (i = 0; i <= ((int)(sizeof(inputB)) / 2); i++)
    	{
    		*outputB += lookupTable(inputB[i], inputB[i+1]);
    		i++;
    	}
    
    	printf((char *)outputB);
    }
    
    int lookupTable(char dataCharacter1, char dataCharacter2)
    {
    	int encodation[20];
    	int j;
    
    	for (j = 0; j <= 8; j++)
    	{
    		encodation[j] = encodeB(dataCharacter1, j);
    		j++;
    	}
    }
    
    char encodeB(int dataCharacter, int position)
    {
    	char bEncodation[2];
    
    	if (dataCharacter == 0)
    	{
    		if (position == 0)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    		else if (position == 2)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    		else if (position == 4)
    		{
    			bEncodation[0] = '0';
    			bEncodation[1] = '0';
    			
    			return *bEncodation;
    		}
    		else if (position == 6)
    		{
                                                    bEncodation[0] = '0';
    			bEncodation[1] = '0';
    			
    			return *bEncodation;		}
    		else if (position == 8)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    	}
    }
    If you put a breakpoint on the line: encodation[j] = encodeB(dataCharacter1, j);
    in the lookupTable function, and watch the values of encodation[j] change as you step through, you'll notice that for each even position (encodation[0], encodation[2], etc.) the value is 48 ('0'). However, the value for encodation[4] (and encodation[6]) needs to be '00'. How do I get the output to have 2 zeros rather than just 1? Do I not use an array in the function: char encodeB(int dataCharacter, int position) where I have the nested if statement:

    Code:
    		else if (position == 4)
    		{
    			bEncodation[0] = '0';
    			bEncodation[1] = '0';
    			
    			return *bEncodation;
    		}
    ? Any help is greatly appreciated and I can always post the full program if necessary (it shows what happens to the odd positions of encodation[j]...very similar). Thanks!

  2. #2
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    You need to return a string instead of a character.

  3. #3
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    So are you saying I need to change this function:

    Code:
    char encodeB(int dataCharacter, int position)
    {
    	char bEncodation[2];
    
    	if (dataCharacter == 0)
    	{
    		if (position == 0)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    		else if (position == 2)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    		else if (position == 4)
    		{
    			bEncodation[0] = '0';
    			bEncodation[1] = '0';
    			
    			return *bEncodation;
    		}
    		else if (position == 6)
    		{
                                                    bEncodation[0] = '0';
    			bEncodation[1] = '0';
    			
    			return *bEncodation;		}
    		else if (position == 8)
    		{
    			*bEncodation = '0';
    			return *bEncodation;
    		}
    	}
    }
    to something like this???:

    Code:
    char encodeB(int dataCharacter, int position)
    {
    	char bEncodation[2];
    
    	if (dataCharacter == 0)
    	{
    		if (position == 0)
    		{
    			*bEncodation = "0";
    			return *bEncodation;
    		}
    		else if (position == 2)
    		{
    			*bEncodation = "0";
    			return *bEncodation;
    		}
    		else if (position == 4)
    		{
    			bEncodation[0] = "0";
    			bEncodation[1] = "0";
    			
    			return *bEncodation;
    		}
    		else if (position == 6)
    		{
                                                    bEncodation[0] = "0";
    			bEncodation[1] = "0";
    			
    			return *bEncodation;		}
    		else if (position == 8)
    		{
    			*bEncodation = "0";
    			return *bEncodation;
    		}
    	}
    }
    Just a little confused. Thanks for the help

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Stop and think for a second about what a string is. It's just a set of chars in sequence in memory that end in a '\0'. So it can be an array. But you can also represent a string through a pointer to the first element of the array. So what are you returning? You're returning a char, but a char is a single character. You need to return a sequence of chars, and you can't return an entire array, but you can return a pointer to the first element of your array. I haven't looked at your previous code in this topic, but if you don't have to return a string, don't. Just return a char.

    Next thing to note. You can't return a pointer to a local array and expect nothing to break. All local variables are cleaned up when the function returns, at which point your array will eventually just become corrupt. The solution is to have a local pointer, and then malloc() the necessary amount of memory. This allocated memory from the heap, where it is not destroyed upon function cleanup, so you can return what the pointer points to.

    Lastly, your entire function is rather inefficiently written. Try something like this:

    Code:
    char *encodeB(int dataCharacter, int position)
    {
    	char *szEncode = NULL;
    	if(dataCharacter == 0)
    	{
    		szEncode = calloc(3,sizeof(char)); /* you're using 2 chars + you need a '\0' */
    		switch(position)
    		{
    			case 4:
    			case 6:
    				szEncode[1] = '0';
    			case 0:
    			case 2:
    			case 8:
    				szEncode[0] = '0';
    			break;
    		}
    	}
    	return szEncode; /* The string returned MUST BE FREED LATER ON USING free()!!!! */
    }
    Last edited by MacGyver; 05-02-2007 at 10:55 AM.

  5. #5
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    MacGyver, thank you for the explanation. I'm teaching myself how to do everything via the internet and the C Programming Language book...guess I'm not teaching myself that well

    Stepping through your code helped me understand your technique; however, when I implemented it into my code, it was not producing the result I wanted.

    I changed my code to the below. My difficulty stands at the point of returning from the function encodeB. The variable encodation does not hold the previous returned value (whether it be 0 or 00). And therefore, when lookupTable returns, the variable outputB does not receive the entire value of various 0's. What do I need to change? Thanks for ALL your help!

    Code:
    /* INCLUDES */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char *lookupTable(char dataCharacter1, char dataCharacter2);
    char *encodeB(int dataCharacter, int position);
    
    main()
    {
    	int i;
    	int inputB[4];
    	char *outputB = NULL;
    	
    	outputB = malloc(120);
    
    	/* test sequence 0367 */
    	inputB[0] = 0;
    	inputB[1] = 3;
    	inputB[2] = 6;
    	inputB[3] = 7;
    
    	for (i = 0; i <= ((int)(sizeof(inputB)) / 2); i++)
    	{
    		outputB = lookupTable(inputB[i], inputB[i+1]);
    		i++;
    	}
    
    	printf(outputB);
    }
    
    char *lookupTable(char dataCharacter1, char dataCharacter2)
    {
    	int j;
    	char *encodation = NULL;
    	encodation = malloc(100);
    
    	for (j = 0; j <= 8; j++)
    	{
    		encodation = encodeB(dataCharacter1, j);
    		j++;
    	}
    
    	return encodation;
    }
    
    char *encodeB(int dataCharacter, int position)
    {
    	char *bEncodation = NULL;
    	bEncodation = calloc(3,sizeof(char));
    
    	if (dataCharacter == 0)
    	{
    		switch(position)
    		{
    			case 4:
    			case 6:
    				bEncodation[1] = '0';
    			case 0:                                       
    			case 2:
    			case 8:
    				bEncodation[0] = '0';
    			break;
    		}
    	}
    
    	return bEncodation;
    }

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Take a break from this program for a second, and plot your solution on paper. Break it down to very small and simple steps. Then try to translate each step into C.

  7. #7
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    I plotted everything out on paper and I guess I just don't know enough about C to get my result. When I translated my steps, the compiler does not like my syntax.

    For the function: char *lookupTable(char dataCharacter1, char dataCharacter2)

    I was thinking this line:

    Code:
    encodation = encodeB(dataCharacter1, j);
    should be something like one of these lines, but I guess it's the wrong C syntax.

    Code:
    encodation += encodeB(dataCharacter1, j);
    or

    Code:
    encodation[j] = encodeB(dataCharacter1, j);
    Still looking through the C Programming book I have, but so far not seeing what I need to do to change my line of code.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    slowcoder: I also learned from K&R2. Unfortunately, a few things in there weren't updated in the last edition (and that was in 1988!). You should know that

    1) Today it's considered good practice (and required in C99) to explicitly declare the return type of each function, including main(), even though it defaults to int which is the right type for main(). Read

    http://faq.cprogramming.com/cgi-bin/...&id=1043284376

    2) Even though K&R2 explicitly casts malloc, this isn't necessary anymore (and it wasn't even necessary then - the need was removed between the 1st and 2nd editions). See

    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Check your switch statement. Unless you want the next case to be run "fallen into", you need to have a break statement after each case statement.

  10. #10
    Registered User
    Join Date
    Jul 2006
    Posts
    49

    Question

    robatino, thank you for the links. I changed my main function accordingly and bookmarked that page for future reference so I don't make that mistake again. I'm still digesting the malloc page, and will change my code accordingly with that as well. Thank you for pointing those out for me. Yes, it seems that the K&R2 book is a little outdated.

    Adak, i do want the next case to be run "fallen into". There is no need in my program to have a break statement after each case statement, but thank you.

    My question posed on 05-04-2007 11:45 AM (further explained in my post on 05-03-2007 03:28 PM), still remains. Any help with figuring out what syntax I need to use in order to have the variable encodation to hold the previous returned value (whether it be 0 or 00), it would be greatly appreciated.

    Thanks!

  11. #11
    Registered User
    Join Date
    Jul 2006
    Posts
    49

    Question

    Reading the book over and over, it seems that this line below should work, because it increments the pointer. However, this line doesn't work either. Still confused.

    Code:
    *encodation++ = (char)encodeB(dataCharacter1, j);
    Last edited by slowcoder; 05-08-2007 at 08:27 AM.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Review page 103 in K&R2. Pointer additiion is not:

    *ptr++; /* this increments whatever the ptr is pointing at, not what the pointer is pointing to */

    it's:

    ptr++; /* this is what you want for pointer addition */

    Adak

  13. #13
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    Adak, I read that page over and the explanation wasn't totally clear.

    In my program, I changed it to:

    Code:
    encodation = encodeB(dataCharacter1, j);
    encodation++;
    but when I did: printf(encodation);

    Nothing printed, and therefore, did not work. So I wasn't sure if it meant: encodation++ = encodeB(dataCharacter1, j);

    but that didn't work, because I received error C2106 left operand must be l-value. I'm going to re-read the whole chapter, but if anyone has a better explanation of this, it would be rather helpful at this point. Thanks!

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by slowcoder View Post
    Adak, I read that page over and the explanation wasn't totally clear.

    In my program, I changed it to:

    Code:
    encodation = encodeB(dataCharacter1, j);
    encodation++;
    but when I did: printf(encodation);

    Nothing printed, and therefore, did not work. So I wasn't sure if it meant: encodation++ = encodeB(dataCharacter1, j);

    but that didn't work, because I received error C2106 left operand must be l-value. I'm going to re-read the whole chapter, but if anyone has a better explanation of this, it would be rather helpful at this point. Thanks!
    OK, the ptr with the * is what the pointer is referencing, a ptr without a * is the actual address. When you increment ++, you want to increment the address to move the pointer up to the next address. If you ++ the *ptr, you'll be adding 1 to the thing the pointer is referencing. So if the pointer was pointing to a variable worth 2 apples, you'd now have 3 apples.

    If it was an array, and you ++'d the pointer at the 5th element, which had a value of 9, it would now be pointing at the 6th array element, with a completely different value (perhaps).

    If you ++'d the *pointer when it was pointing to the 5th array element, and it had the value of 9, that value would be changed to 10, and the pointer would still point to the same array element.

    You don't want to print the pointer, you want to print the *pointer.

    Adak
    Last edited by Adak; 05-08-2007 at 08:39 AM.

  15. #15
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    I have a program that I've been using as reference (not written by me and fully works), and I noticed that there's a line of code:

    Code:
    *txt_ptr++ = '\\';
    where \\ is added to the end when it gets printed. So that's why I thought doing:

    Code:
    *encodation++ = encodeB(dataCharacter1, j);
    would work. I just want to add whatever encodeB() returns to the end of encodation. Still can't get it working with:

    Code:
    encodation = encodeB(dataCharacter1, j);
    encodation++;


    And when I did:

    Code:
    printf(*encodation);
    as Adak recommended, I received two warnings: C4047: 'function' : 'const char *' differs in levels of indirection from 'char' and C4024: 'printf' : different types for formal and actual parameter 1. Am I really suppose to print *encodation? If so, what would I have to change/add to the syntax?

    Thank you Adak for your explanation. Still looking through more documents online to get a better understanding. Just trying to get this working so I can really understand this stuff better....much easier when you have a working example...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointers & arrays and realloc!
    By zesty in forum C Programming
    Replies: 14
    Last Post: 01-19-2008, 04:24 PM
  2. Output an array in a textbox
    By Diablo02 in forum C# Programming
    Replies: 5
    Last Post: 10-18-2007, 03:56 AM
  3. My Arrays!!!, My Arrays!!! Help!?
    By llcool_d2006 in forum C++ Programming
    Replies: 1
    Last Post: 12-10-2006, 12:07 PM
  4. Input / Output help (arrays)
    By fp123 in forum C++ Programming
    Replies: 1
    Last Post: 01-15-2006, 12:30 PM
  5. counting and output, with arrays and functions
    By Wraithan in forum C++ Programming
    Replies: 7
    Last Post: 12-05-2005, 12:46 AM