Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing arrays to functions 3

Status
Not open for further replies.

Greenleaf

Programmer
Feb 14, 2002
93
IT
Hello,
seems like I have a problem in passing an array to a function and then passing the value back to the main program.
This program reads a sentence and converts the first letter in a capital letter, if needed, and converts the rest in non capital.

Code:
#define maxarray 40

#include <stdio.h>
#include <string.h>

char change(char word[]);

void main()
{
	char word[maxarray];
	printf(&quot;\nIntroduce sentence  &quot;);
	gets(word);
	word=change(word);
        printf(&quot;\nThe sentence is:  %s&quot;, word);

}

char change(char word[])
{
      int i;
      if (( 97 <= word[0]) && (word[0] <= 122 ))
	  word[0] = word[0]-32;
	for (i=1; i< maxarray; ++i)
	  {
	     if (( 65 <= word[i]) && (word[i] <= 90))
	       word[i]= word[i]+32;
	  }
       return word;	
}

I can't pass the word back to main. It signals an error.
I could as well make the function print the final sentence but that's not what I want.
Can anyone help me?



 
For one thing you're attempting to pass a character array back through somthing that is defined as a single character.

The real issue however is that you don't understand what is going on. when you pass an array it is actualy being passed by reference. When you make changes to something that was passed by reference the changes are made to the actual variable. So in your case you actualy don't need a return at all.

-Sean
 
try the following code

char change(char *word, int length_of_word)
{// length of word is the length of array word
int i;
if (( 97 <= word[0]) && (word[0] <= 122 ))
word[0] = word[0]-32;
for (i=1; i< maxarray; i++)
{
if (( 65 <= word) && (word <= 90))
word= word+32;
}
return word;
}


 
Well Greenleaf,

You have many errors in your code actually. Logical aswell as symantical. Lets start with the logical errors.

First Error:

Condition
Code:
if (( 97 <= word[0]) && (word[0] <= 122 ))
makes not much of a sence. I guess you want to check for a small case alphabet? the condition should be:
Code:
if (( 97 >= word[0]) && (word[0] <= 122 ))
. Similar correction need to be done for checking the uppercase alphabets.

Second Error:

When you declare an array, its by default
Code:
static
i.e. it cannot be assigned a new value. U may only copy a string to it using indexing or strcpy. I know this may be a bit confusing, but it has to do with pointers that I cant explain in this short space.

Further more, the array when sent to a function, its reference goes to it. Therefore, whatever changes you do to it would be reflected automatically in your calling program, you DONT have to return it.

One more thing, you CANNOT return an array from a function. Thats limited in C. Finally, what you need to do is:

1) replace word=change(word); to just change(word); (like gets(word))
2)remove the return statement and change the return type to void.
3)Correct the conditional IF statements, as indicated in my post.

Your code will jump to action.

ICICI: I am sorry buddy, your code is a logical disaster! I am sure you didnt compile check it before posting. I have no intentions to offend you, please analyze your code with what I have mentioned in this post, u'll see for yourself.

have fun coding...;-)

Roy
user.gif
 
Thanks guys,
yes, I eventually realized that there was something wrong with that array assignment! So I removed it and simply called the function and erased the return line...and the code worked properly.

RoyOBoy, I cannot understand your suggestion about the if statement, my condition works fine.
With the line:
Code:
if (( 97 <= word[0]) && (word[0] <= 122 ))
I want to check if the first letter of the string is non capital and so its ASCII code is between 97 and 122. If it is I want to transform it in a capital letter.
Where's the problem?
What does this
Code:
if (( 97 >= word[0]) && (word[0] <= 122 ))
mean?
Why should the ASCII code of the first letter be less than 97?
Thank you very much for the specification about array copying and passing arrays to a function. I didn't know that. I think I'm gonna print this page!
:)
 
Oh Gosh!:-0 that's a typographical mistake (I guess) What I wanted to write is:
Code:
if(word[0]>=97 && word[0]<=122)

My sincerest apologies to all of you… My brain didn’t compile the program right! (error compiling… not enough memory!) The IF statement IS CORRECT in your code too but it is a convention to keep the variables in the left and constants or values compared to the right.

But, the array name thing stays... you CANT return an array name (statically declared) OR assign anything to an array name.

Sorry for confusing...:p

Roy.
user.gif
 
hmm....how about;

Code:
#define maxarray 40

#include <stdio.h>
#include <string.h>

char *change(char word[]);

void main()
{
    char word[maxarray];
    printf(&quot;\nIntroduce sentence  &quot;);
    gets(word);
    printf(&quot;\nThe sentence is:  %s.\n&quot;, change(word));

}

char *change(char word[])
{
      int i;
      if (( 97 <= word[0]) && (word[0] <= 122 ))
      word[0] = word[0]-32;
    for (i=1; i< maxarray; ++i)
      {
         if (( 65 <= word[i]) && (word[i] <= 90))
           word[i]= word[i]+32;
      }
       return word;    
}

tinker tinker..... Rob
&quot;Programming is like art...It makes me feel like chopping my ear off.&quot;

- Currently down
 
Hi Rob,

You got a neat solution there...:)I I would want to add a line here...

Actyally most of the string related functions implement this signature (eg: char *gets( char *buffer );) But, if not used cautiously, this can lead you to problems!

What I want to focus on is the returning value. The return in a reference, the same reference that the function got as one of its arguments.

Where's the problem? well, IF you declare a pointer within that function and return that reference, it would lead to unexpected behaviour of the program as the reference returned was created locally (may be by malloc()) within the function which will be outside the area of main() (or any function that called it) after the function ends. Now the returned reference is technically refered to a Dangling reference, i.e. it is pointing to a memory that isnt allocated to it.

I hope the message is conveyed...%-)

Roy
user.gif
 
Hey guys,

There's a slight mistake in my post. Note the point I told about returning a reference from a function. Error is caused when you return a reference of an array within the function (eg: char str[20];) b'coz, in this case, the array is destroyed after the function terminates.

When malloc() is used, this becomes more of the programs responsibility to destroy the allocation and till it isnt free()ed explicitly, all the memory allocated remain in the memory (may be unreferenced, this is termed as garbages) Dangling reference is a pointer pointing to a memory not allocated to it officially!

Pardon my mistake :p

Roy
user.gif
 
Hello Rob & Roy,
thanks for the concerning, guys.
But can you explain me what does the star mean when placed before the name of the function?
 
Well... am sorry, I assumed...:p ne way.

The * placed before the name of the function means its going to return a reference (a memory address) of type mentioned before the star (char in our case) Thus in our case, the function is returning character reference (memory address for storing char data).

May be you'll need to read about pointers before you can fully appreciate this property of C/C++. There's a nice FAQ also on pointers in this forum's faq but I wont recomend you to read that unless you read a starter book on pointers in C.

BTW, the star like thing is called an asterisk.

Roy.
user.gif
 
Ok Roy, understood but is there a reason to use this * version instead of the former one (void change...no return etc etc)?
Anyway, as you have taken pity of me (I hope so) can you tell me why this following code makes my system crash???

Code:
void copy(int index, char model[], char new[]);

void main()
{
       char source[dimmax], destin[dimmax];
       int i,numb;
       printf(&quot;\nIntroduce source string\n&quot;);
       gets(source);
       printf(&quot;\nIntroduce number of char to be copied &quot;);
       scanf(&quot;%d&quot;, &numb);
       for  (i=0; i < dimmax; ++i)
	 destin[i]=0;
       copy(numb, source, destin);
     
}

void copy(int index, char model[], char new[])
{
    int i,j;
    j=dimmax-index;
    for (i= 0; i< index; ++i)
      {
	 new[i]=model[j];
	 j=j+1;
      }
    printf(&quot;\nThe new string is: %s&quot;, new);
}
It should copy the last &quot;numb&quot; characters of a string into a new string.
What disaster have I done this time?......:-(
 
Hey Greenleaf,

If I made you feel that way (pity thing), my sincere apologies... ::)

Its not necessary to use the char * version instead of void. References are returned (in case of char *) to use it immediately like in
Code:
strcpy (str2, change(str1))
or as in the example given by Rob. void is also ok but you'll not be able to do the above mentioned kinda stuff. As I told you earlier, gets() has the same signature but we dont use it that way (we needn't mostly).

Your New problem: Well,
Code:
dimmax
is a defined name I suppose. Let me assume a value 100 for it and say you enter a string &quot;GreenLeaf&quot; and int 4. According to you, it should copy &quot;Leaf&quot;? BUT! in your logic, you said
Code:
j=dimmax-index;
! So? j would compute to 100-4 and that is? 96! and you copy chars 96 to 100 to your destination that ought to be Garbo!

What you need: U need to correct the
Code:
j=dimmax-index;
with
Code:
j=strlen(model)-index;
copying till the end of the string (not the char array!) and the loop should run till
Code:
i<=index;
so as to copy the NULL char as well, terminating the new string. See the code below:
Code:
 int i,j;
    j=strlen(model)-index;
    for (i= 0; i<
Code:
=
Code:
index; ++i)
         new[i]=model[j+i];

    printf(&quot;\nThe new string is: %s&quot;, new);

I hope it was not to lengthy an explainantion...;-)

Roy
user.gif
 
Strings and string handleing is a VERY touchy subject in C. My advise is to follow RoyOBoy's advice, he most definately knows what he's talking about. Actually, I would have preffered to use;

char *change( char *string_to_change);

Useing this meathod however, I'm unsure as to how to allocate a certain ammount of memory for the string...Care to explain, Roy?

:p

Rob
&quot;Programming is like art...It makes me feel like chopping my ear off.&quot;

- Currently down
 
On a side note, be very careful with pointers (the *'s)...I advise reading up on the subject before useing them. Since you are literaly storing information to an address on your system, if you initialize it wrong, or make a wrong call it could be harmfull (on some rare occasions) to your system. Rob
&quot;Programming is like art...It makes me feel like chopping my ear off.&quot;

- Currently down
 
Roy, you're great!That's fine! I was worried because whenever I run my code, my system had a complete breakdown!
But why if, for example, you put dimmax=9 and write GreenLeaf with numb=4 it doesn't work?
One thing: I suspect it's
Code:
for (i= 0; i<=index; ++i)
     new[i]=model[
j
Code:
];

Hey, I'm not offended at all, I'm thankful for your help and I deserve to get scolded for my bad errors!!(-:

>
 
GreenLeaf, The statemens posted by you aren't correct actually. It should be
Code:
new[i]=model[j
Code:
+i
Code:
];
If I assume it to be a typo err I can see yet another small logical err. That is the dimmax value you assumed. If you take 9 and store GreenLeaf in to it, it wouldn't leave space for a NULL char and would lead to an overflow of the array limit when system tries to put NULL at the end of the string (that happens to be the 10th location of the array)

Otherwise, the code is perfect. Always keep in mind to take the size of the array to be ONE plus the length of the expected string (better still, take couple of locations extra)

have fun coding...;-)

Roy.
user.gif
 
Thanks Rob for your comments, Could you please eloborate your question a bit ? When and where do you want to allocate memory, within the function or from the calling function based on the string returned from the function!

I will certainly try for a solution then...:p

Roy.
user.gif
 
Well, given the example, we will want to allocate the memory prior to calling the function. (since we will actually be storing the information in the main() function, from user input). HOWEVER the variable we're storing the information in is not the same as the variable initialized within the change function...so wouldn't we have to allocate memory for both variables? If so...

we use something like this in our main function...

malloc(orig_string, 80); /* I believe this is how
/* malloc is used..I havn't
/* used it in a while
gets(orig_string);
printf(&quot;The sentance is: %s&quot;, change(orig_string));

then in our change function...

char *change( char *str_to_change) {
malloc(str_to_change, 80);
...
...
...
}

This is how you would assume it would be done (minus any minor syntax errors, I'm doing this from work, and quickly so give me some credit ;P), but I'm not sure if it is how it WOULD be done...perhaps a global variable would be more appropriate, and to be allocated prior to receiving the input?

What say you? ;)

Rob
&quot;Programming is like art...It makes me feel like chopping my ear off.&quot;

- Currently down
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top