473,394 Members | 1,709 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Need 2 values from function

JD
Hi guys

What if I need to return two values from a function. What's the best way
to do it?

Function is to load a text file into memory like so:

-----8<-----

char *LoadFile(char *infile)
{
FILE *f;
int c;
int bytesread, bytestotal;
char *buf, *p, *tmp;

if ((f = fopen(infile, "r")) == NULL) {
printf("Can't open \"%s\" for reading\n", infile);
return NULL; /* NULL means failure to calling function */
}

bytesread = 0;
bytestotal = 0;
buf = NULL;
while ((c = fgetc(f)) != EOF) {
if (bytestotal - bytesread == 0) {
bytestotal += 1024;
tmp = realloc(buf, bytestotal);
if (tmp == NULL) {
printf("*** Out of memory ***\n");
return NULL;
}
buf = tmp;
p = buf + bytesread;
}
*p++ = c;
bytesread++;
}

*p = '\0'; /* terminate string...could this be out of bounds in
certain situations? */

fclose(f);
return buf;
}

----->8-----

I need to return the pointer to the memory as well as "bytestotal" so I
can allocate another block of memory for working with the data (copying
it back and forth to do operations on it etc.) It seems inefficient to
call the function twice so I have two blocks of memory.

I'm aware of some possibilities: use "call by reference", return a
struct, use a global variable. I'm just not sure which to choose and why.

Thanks!
Jan 17 '06 #1
9 2092
Ico
JD <jd@example.net> wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?
A common way is to pass pointers to your function for every return
variable, which contents are changed from within the function.

For example : (code not tested)

void somefunc(int a, int *b, int *c)
{
*b = a * 2;
*c = a * 3;
}

You could call this with

int value = 10;
int timestwo;
int timesthree;

somefunc(value, &timestwo, &timesthree);

printf("%d %d\n", timestwo, timesthree);
If you have to return a lot of values, more the four or five or so, it
might be preferrable to create a struct for passing the variables, like
so :

struct stuff {
int timestwo;
int timesthree;
int timesfour;
int timesfive;
};

void somefunc(int a, struct stuff *data) {
data->timestwo = a * 2;
data->timesthree = a * 3;
data->timesfour = a * 4;
data->timesfive = a * 5;
}

and call it like
int value = 10;
struct data;

somefunc(a, &data);

printf("%d %d %d %d\n", data.timestwo, data.timesthree,
data.timesfour, data.timesfive);

[ snipped code example ]
I need to return the pointer to the memory as well as "bytestotal" so I
can allocate another block of memory for working with the data (copying
it back and forth to do operations on it etc.) It seems inefficient to
call the function twice so I have two blocks of memory.

I'm aware of some possibilities: use "call by reference", return a
struct, use a global variable. I'm just not sure which to choose and why.


'Call by reference' is not part of the C language. The pointer method I
described above can be used to accomplish similar things.

Global variables are usually considered a bad thing; if you can avoid
it, do not use them.

Ico

--
:wq
^X^Cy^K^X^C^C^C^C
Jan 17 '06 #2
JD wrote:

Hi guys

What if I need to return two values from a function.
What's the best way to do it?

Function is to load a text file into memory like so:

-----8<-----

char *LoadFile(char *infile)
{
FILE *f;
int c;
int bytesread, bytestotal; I'm aware of some possibilities: use "call by reference",


That's OK, if this is what you mean:

char *LoadFile(char *infile, int *bytestotal);

--
pete
Jan 17 '06 #3
On Tue, 17 Jan 2006 20:19:13 +0000, in comp.lang.c , JD
<jd@example.net> wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?
either use pointers
void modifies_a_and_b( char* a, int* b);
or return a struct

struct twovals {char a; int b; };
struct twovals fn_returns_struct(void);
I'm aware of some possibilities: use "call by reference",
Aint no such thing in C - all calls are by value. You can pass a
pointer in, as above.
return a struct, use a global variable.
The last is a bad idea. Don't use globals if at all possible.
I'm just not sure which to choose and why.


It totally depends on what you do with the data.
Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Jan 17 '06 #4
JD wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?

There is no fixed rules as to whether returning a struct containing the
values, or passing pointers to the result as parameters to the function
is best.

Which you use is dependant on the types you are returning and the
machine you are using. For example if your return values as a struct
fit a machine register, it may be best to return a struct.

Play and see which works best for you in your situation.

--
Ian Collins.
Jan 17 '06 #5
JD wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?

Function is to load a text file into memory like so:

-----8<-----

char *LoadFile(char *infile)
{
FILE *f;
int c;
int bytesread, bytestotal;
char *buf, *p, *tmp;

if ((f = fopen(infile, "r")) == NULL) {
printf("Can't open \"%s\" for reading\n", infile);
return NULL; /* NULL means failure to calling function */
}

bytesread = 0;
bytestotal = 0;
buf = NULL;
while ((c = fgetc(f)) != EOF) {
if (bytestotal - bytesread == 0) {
bytestotal += 1024;
tmp = realloc(buf, bytestotal);
if (tmp == NULL) {
printf("*** Out of memory ***\n");
return NULL;
}
buf = tmp;
p = buf + bytesread;
}
*p++ = c;
bytesread++;
}

*p = '\0'; /* terminate string...could this be out of bounds in
certain situations? */

fclose(f);
return buf;
}

----->8-----

I need to return the pointer to the memory as well as "bytestotal" so I
can allocate another block of memory for working with the data (copying
it back and forth to do operations on it etc.) It seems inefficient to
call the function twice so I have two blocks of memory.

I'm aware of some possibilities: use "call by reference", return a
struct, use a global variable. I'm just not sure which to choose and why.

Thanks!

The simpliest is the best in most cases ;-)

use the return for the bytestotal : then if error occurs yoy can return -1 for example...
use "call by ref" for the buffer

==> then you should verify buf == NULL first ...

xavier
Jan 17 '06 #6

JD wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?

Function is to load a text file into memory like so:
<code snipped for brevity>

I need to return the pointer to the memory as well as "bytestotal" so I
can allocate another block of memory for working with the data (copying
it back and forth to do operations on it etc.) It seems inefficient to
call the function twice so I have two blocks of memory.

I'm aware of some possibilities: use "call by reference", return a
struct, use a global variable. I'm just not sure which to choose and why.

Thanks!


This looks like yet another job for FreeDOS Edlin! Grab it from ibiblio
or alt.sources and you can see for yourself how it manipulates buffers.

Gregory Pietsch

Jan 17 '06 #7
JD wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?


Always start by checking a newsgroup's FAQ before posting. Your
question is found at <http://c-faq.com/misc/multretval.html>, "How can I
return multiple values from a function?"
Jan 17 '06 #8
structures are passed by value (i.e. they are (shallow) copied)
so I'd suggest something along the lines of:
struct ret_vals { int ret_val1; int ret_val2; };

struct ret_vals
my_func( int input_param )
{
struct ret_vals = { 0 };
/* do your stuff*/
ret_vals.ret_val1 = 0 /*or something from your stuff*/;
trt_vals.ret_val2 = 0 /*or something from your stuff*/;
return ret_vals;
}

/* if there are many values to return and you are concerned about
efficiency
then consider passing in a pointer to a struct retvals
*/
"Ico" <us****@zevv.nl> wrote in message
news:43**********************@dreader24.news.xs4al l.nl...
JD <jd@example.net> wrote:
Hi guys

What if I need to return two values from a function. What's the best way
to do it?


A common way is to pass pointers to your function for every return
variable, which contents are changed from within the function.

For example : (code not tested)

void somefunc(int a, int *b, int *c)
{
*b = a * 2;
*c = a * 3;
}

You could call this with

int value = 10;
int timestwo;
int timesthree;

somefunc(value, &timestwo, &timesthree);

printf("%d %d\n", timestwo, timesthree);
If you have to return a lot of values, more the four or five or so, it
might be preferrable to create a struct for passing the variables, like
so :

struct stuff {
int timestwo;
int timesthree;
int timesfour;
int timesfive;
};

void somefunc(int a, struct stuff *data) {
data->timestwo = a * 2;
data->timesthree = a * 3;
data->timesfour = a * 4;
data->timesfive = a * 5;
}

and call it like
int value = 10;
struct data;

somefunc(a, &data);

printf("%d %d %d %d\n", data.timestwo, data.timesthree,
data.timesfour, data.timesfive);

[ snipped code example ]
I need to return the pointer to the memory as well as "bytestotal" so I
can allocate another block of memory for working with the data (copying
it back and forth to do operations on it etc.) It seems inefficient to
call the function twice so I have two blocks of memory.

I'm aware of some possibilities: use "call by reference", return a
struct, use a global variable. I'm just not sure which to choose and why.


'Call by reference' is not part of the C language. The pointer method I
described above can be used to accomplish similar things.

Global variables are usually considered a bad thing; if you can avoid
it, do not use them.

Ico

--
:wq
^X^Cy^K^X^C^C^C^C

Jan 18 '06 #9
(I realize this article is somewhat old; I have been saving it
to reply to, while hoping someone else would point this out first.)

In article <43*************@individual.net> JD <jd@example.net> wrote:
What if I need to return two values from a function. What's the best way
to do it?
Lots of people answered that part just fine.
char *LoadFile(char *infile)
{
FILE *f;
int c;
int bytesread, bytestotal;
char *buf, *p, *tmp;

if ((f = fopen(infile, "r")) == NULL) {
printf("Can't open \"%s\" for reading\n", infile);
return NULL; /* NULL means failure to calling function */
}

bytesread = 0;
bytestotal = 0;
buf = NULL;
while ((c = fgetc(f)) != EOF) { [snip code that expands the buffer in units of 1024 chars at a time] }

*p = '\0'; /* terminate string...could this be out of bounds in
certain situations? */
The answer to the question in the comment is "yes". In fact, it
should now be obvious that "p" will be invalid in at least one
case. What happens if the very first fgetc() returns EOF?

(In fact, writing on *p is invalid whenever the size of the file
is congruent to zero mod 1024, given the snipped code. A string
of length N requires N+1 bytes of storage.)
fclose(f);
return buf;
}

--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 6 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Jeff Wagner | last post by:
I am in the process of learning Python (obsessively so). I've been through a few tutorials and read a Python book that was lent to me. I am now trying to put what I've learned to use by rewriting...
7
by: angelasg | last post by:
Here is sample data I'm working with: ID ShiftDate SegTime 99 5/2/2005 5/2/2005 1:00:00 PM 99 5/2/2005 5/2/2005 1:04:00 PM 99 5/2/2005 5/2/2005 1:43:00 PM 99 5/2/2005...
2
by: Mike Button | last post by:
Hello all, I am really really desperate on what I should do, and I am asking for help from anyone in this newsgroup, here's the situation: I am creating a form that is being run on a server...
3
by: ash | last post by:
Hey I am new, but I don't have time to intruduce myself yet. I am intro to C++ and this is a programme I have to write. all the direction are here, It will be very nice of someone to figure this...
4
by: Nathan Benefield | last post by:
I currently have a spreadsheet tracking votes on legislation in a matrix type format. It is something like this Name Act1 Veto1 Act1A Jones yes No Yes Johnson Yes ...
11
by: Alan Mailer | last post by:
A project I'm working on is going to use VB6 as a front end. The back end is going to be pre-existing MS Access 2002 database tables which already have records in them *but do not have any...
10
by: CuTe_Engineer | last post by:
hii, i have cs assignment i tried to solve it but i still have many errors , plzz help mee :"< it`s not cheating becuz i`ve tried & wrote the prog. i just wanna you to show me my mistakes ...
2
Dormilich
by: Dormilich | last post by:
Hi, I'm testing my classes for a web page and I stumble upon an error I don't have a clue what it means: Error: Fatal error: Can't use method return value in write context in "output.php" on...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.