Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > strings and functions

Reply
Thread Tools

strings and functions

 
 
c_monty
Guest
Posts: n/a
 
      08-22-2003

I am used to Delphi and VB, where functions can return strings. I
recently starting learning C and my findings are that you can have
external functions build strings, but the function cannot return the
string itself, rather, it needs to update a variable that is an array or
points to an array. Correct?



Below is a 'simple' test to work with a string that was created in an
external function (and external file). Based on the result I get (_@),
I know I don't fully "get it" yet. Any help would be appreciated.



//MAIN.C

#include<stdio.h>



main()

{

char *data_from_function;



my_function(data_from_function);

printf("Data results from My Function: %s\n");

}



//MYFUNCTION.C



my_function(char *strData)

{

strData = "HELLO WORLD\n";

}



(Linux 9 i386)

#gcc main.c myfunction.c

#./a.out



Data results from My Function: _@


--
Posted via http://dbforums.com
 
Reply With Quote
 
 
 
 
Thomas Matthews
Guest
Posts: n/a
 
      08-22-2003
c_monty wrote:
> I am used to Delphi and VB, where functions can return strings. I
> recently starting learning C and my findings are that you can have
> external functions build strings, but the function cannot return the
> string itself, rather, it needs to update a variable that is an array or
> points to an array. Correct?
>
> Below is a 'simple' test to work with a string that was created in an
> external function (and external file). Based on the result I get (_@),
> I know I don't fully "get it" yet. Any help would be appreciated.
>
> //MAIN.C
>
> #include<stdio.h>
> main()


The main() function should have a return type:
int main(void)


> {
> char *data_from_function;
> my_function(data_from_function);
> printf("Data results from My Function: %s\n");


Perhaps this should have been:
printf("Data results from my_function: %s\n",
data_from_function); /* you forgot this */
> }


> //MYFUNCTION.C
> my_function(char *strData)
> {
> strData = "HELLO WORLD\n";
> }


Pointers are passed by value in C.
If you want to change a pointer, pass the address
or a pointer to the pointer:
void my_function(char * * strData)
{
*strData = "Hellow World\n";
}

or copy the data to the location of the original
array:
void my_other_function(char * strData)
{
strcpy(strdata, "Hello again.\n");
return;
}

int main(void)
{
char string_one[640];
char * string_two;

my_function(&string_two);
my_other_function(string_one);
printf("Results:\n%s\n%s\n",
string_one, string_two);
return 0;
}

>
> (Linux 9 i386)
> #gcc main.c myfunction.c
> #./a.out
>
> Data results from My Function: _@
> --
> Posted via http://dbforums.com



--
Thomas Matthews
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html

 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      08-22-2003
c_monty wrote:
>
> I am used to Delphi and VB, where functions can return strings. I
> recently starting learning C and my findings are that you can have
> external functions build strings, but the function cannot return the
> string itself, rather, it needs to update a variable that is an array or
> points to an array. Correct?


Pretty much. "C functions can't return strings" is just
a special case of "C functions can't return arrays," because
a string in C is just an array of `char' elements formatted
in a particular way. Recommended reading: Section 6 "Arrays
and Pointers" in the comp.lang.c Frequently Asked Questions
(FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

> Below is a 'simple' test to work with a string that was created in an
> external function (and external file). Based on the result I get (_@),
> I know I don't fully "get it" yet. Any help would be appreciated.
>
> //MAIN.C
>
> #include<stdio.h>
>
> main()
>
> {
>
> char *data_from_function;
>
> my_function(data_from_function);
>
> printf("Data results from My Function: %s\n");


There are minor solecisms elsewhere, but this is the first
Real Live Error: You've used the "%s" specifier to tell printf()
to output a string, but you haven't told printf() what string
you want it to output! printf() trusts you, looks in the place
where the string's `char*' pointer would have been if you'd
supplied one, gets some kind of garbage, and then there's no
guarantee of what might happen. You've landed yourself in the
perilous land called Undefined Behavior.

>
> }
>
> //MYFUNCTION.C
>
> my_function(char *strData)
>
> {
>
> strData = "HELLO WORLD\n";


Here's the second Real Live Error: You don't understand
that C arguments are passed by value, not by reference.
See Question 4.8 in the FAQ.

> }
>
> (Linux 9 i386)
>
> #gcc main.c myfunction.c


Since you're still somewhat shaky in C, it would be a
good idea to crank up gcc's warning levels a bit. I use

gcc -Wall -W -ansi -pedantic -O2 ...

.... except that I omit "-ansi -pedantic" for programs that
can't tolerate such rigidity, and I raise the optimization
level higher than "-O2" when circumstances warrant it.

> #./a.out
>
> Data results from My Function: _@


Could have been anything at all, or nothing at all.
Undefined Behavior is, well, undefinable. Folks around
here are fond of saying U.B. might make demons fly out
of your nose. Years ago on this same newsgroup, people
had a wider variety of imaginative U.B. examples, but the
nasal demons seem to have crowded out the creativity.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Martin Dickopp
Guest
Posts: n/a
 
      08-22-2003
c_monty <(E-Mail Removed)> writes:

> I am used to Delphi and VB, where functions can return strings. I
> recently starting learning C and my findings are that you can have
> external functions build strings, but the function cannot return the
> string itself, rather, it needs to update a variable that is an array or
> points to an array. Correct?


Correct.

> Below is a 'simple' test to work with a string that was created in an
> external function (and external file). Based on the result I get (_@),
> I know I don't fully "get it" yet. Any help would be appreciated.
>
> //MAIN.C
>
> #include<stdio.h>
>
> main()


int main (void)

> {
> char *data_from_function;
>
> my_function(data_from_function);
>
> printf("Data results from My Function: %s\n");


Do you mean `printf("Data results from My Function: %s\n", data_from_function);'?

> }


Insert `return 0;' before the closing brace.

>
> //MYFUNCTION.C
>
> my_function(char *strData)
> {
> strData = "HELLO WORLD\n";
> }


`strData' is local to `my_function'. You make `strData' point to a string
literal. Then the function execution ends, and the value of `strData' is
forgotten.

You can return a string literal (more precisely: a pointer to the first
character of string literal) from a function like this:


#include <stdio.h>

const char *my_function (void)
{
return "HELLO WORLD";
}

int main (void)
{
printf ("Data results from My Function: %s\n", my_function ());
return 0;
}


A string literal cannot be modified. If you need to modify the string, you
must copy it to an array:


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

void my_function (char *const buffer)
{
strcpy (buffer, "HELLO WORLD");
}

int main (void)
{
/* Must be large enough for the string,
including the terminating '\0' character. */
char my_buffer [12];

my_function (my_buffer);

my_buffer [1] = 'A';

printf ("Data results from My Function: %s\n", my_buffer);
return 0;
}


> (Linux 9 i386)


<OT>
No such thing. Linux is currently at version 2.4.21; the development branch
is at version 2.6.0-test3.
</OT>

> #gcc main.c myfunction.c


Please invoke gcc with at least the following flags: -O -Wall -ansi -pedantic

I recommend `-W' in addition to that.

Martin
 
Reply With Quote
 
Ed Morton
Guest
Posts: n/a
 
      08-22-2003


On 8/22/2003 1:31 PM, pete wrote:
> c_monty wrote:
>

<snip>

> char *my_function(char *strData)
> {
> strData = malloc(sizeof "HELLO WORLD\n");
> if (strData) {
> strcpy(strData, "HELLO WORLD\n");
> }
> return strData;
> }
>


Why would you have "my_function" take an argument in this case? Wouldn't you
really write this as:

char *my_function()
{
char *strData;
strData = malloc(sizeof "HELLO WORLD\n");
if (strData) {
strcpy(strData, "HELLO WORLD\n");
}
return strData;
}

so that instead of being called as:

> data_from_function = my_function(data_from_function);


it can be called as:

data_from_function = my_function();

Regards,

Ed.


 
Reply With Quote
 
ataru@nospam.cyberspace.org
Guest
Posts: n/a
 
      08-22-2003
Thomas Matthews <(E-Mail Removed)> broke the eternal silence and spoke thus:

> void my_function(char * * strData)
> {
> *strData = "Hellow World\n";
> }


This is bad (right?) since strData now points to a constant string that will
vanish when my_function returns...

> void my_other_function(char * strData)
> {
> strcpy(strdata, "Hello again.\n");
> return;
> }


Also bad, since you don't know in general how much space strData has
associated with it, if any.

If I've done foot-in-mouth again here, I apologize

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
 
Reply With Quote
 
Michael B Allen
Guest
Posts: n/a
 
      08-22-2003
On Fri, 22 Aug 2003 13:48:54 -0400, c_monty wrote:


> I am used to Delphi and VB, where functions can return strings. I
> recently starting learning C and my findings are that you can have
> external functions build strings, but the function cannot return the
> string itself, rather, it needs to update a variable that is an array or
> points to an array. Correct?


These other environments are likely returning pointers (Java calls them
references) as well. C permits pointer arthmetic which gives C it's
razor's edge. Be careful.

> my_function(data_from_function);
>
> printf("Data results from My Function: %s\n");


You just forgot to add the string you want to print:

printf("Data results from My Function: %s\n", data_from_function);

In C the way to "return strings" is to return a pointer to an array
of characters:

char *
tostr(void)
{
return "hello";
}

Mike
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      08-22-2003
Ed Morton wrote:
>
> On 8/22/2003 1:31 PM, pete wrote:
> > c_monty wrote:
> >

> <snip>
>
> > char *my_function(char *strData)
> > {
> > strData = malloc(sizeof "HELLO WORLD\n");
> > if (strData) {
> > strcpy(strData, "HELLO WORLD\n");
> > }
> > return strData;
> > }
> >

>
> Why would you have "my_function" take an argument in this case?


It's a vestigial feature from the original post.

> Wouldn't you really write this as:
>
> char *my_function()
> {
> char *strData;
> strData = malloc(sizeof "HELLO WORLD\n");
> if (strData) {
> strcpy(strData, "HELLO WORLD\n");
> }
> return strData;
> }
>
> so that instead of being called as:
>
> > data_from_function = my_function(data_from_function);

>
> it can be called as:
>
> data_from_function = my_function();


Yes, I think that's better.

--
pete
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      08-22-2003
(E-Mail Removed) wrote:
>
> Thomas Matthews <(E-Mail Removed)>
> broke the eternal silence and spoke thus:
>
> > void my_function(char * * strData)
> > {
> > *strData = "Hellow World\n";
> > }

>
> This is bad (right?) since strData now points to a
> constant string that will vanish when my_function returns...


No. Those kinds of strings persist.
The strData pointer itself, will disappear,
but the desired side effect will happen.
The external pointer that *strData points to,
will be pointed at the string.

>
> > void my_other_function(char * strData)
> > {
> > strcpy(strdata, "Hello again.\n");
> > return;
> > }

>
> Also bad, since you don't know in general how much space strData has
> associated with it, if any.


That particular criticism is valid.

This works:

#include <stdio.h>

void my_function(char * * strData)
{
*strData = "Hellow World\n";
}

int main(void)
{
char *data_from_function;

my_function(&data_from_function);
printf("Data results from My Function: %s\n",
data_from_function);
return 0;
}

--
pete
 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      08-22-2003
(E-Mail Removed) wrote:

> Thomas Matthews <(E-Mail Removed)> broke the eternal silence and spoke thus:
>
>
>>void my_function(char * * strData)
>>{
>> *strData = "Hellow World\n";
>>}

>
>
> This is bad (right?) since strData now points to a constant string that will
> vanish when my_function returns...


No, the location of the literal will persist.



>>void my_other_function(char * strData)
>>{
>> strcpy(strdata, "Hello again.\n");
>> return;
>>}

>
>
> Also bad, since you don't know in general how much space strData has
> associated with it, if any.
>
> If I've done foot-in-mouth again here, I apologize


Yes, this is also bad, but it is another alternative.
Welcome to the problem with C arrays.

--
Thomas Matthews
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
functions to escape and unescape strings in rails Tony Augustine Ruby 0 07-22-2010 07:02 AM
id functions of ints, floats and strings zillow10@googlemail.com Python 6 04-06-2008 03:59 AM
Strings, Strings and Damned Strings Ben C Programming 14 06-24-2006 05:09 AM
Catching std::strings and c-style strings at once Kurt Krueckeberg C++ 2 11-17-2004 03:53 AM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM



Advertisments