Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > subroutine in c

Reply
Thread Tools

subroutine in c

 
 
rudra
Guest
Posts: n/a
 
      04-18-2010
I have 2 subroutine in c(which is ultimately called by fortran):
$ cat bit_unm.c
/***********************************************
This code returns the machine bit
to the program bitinit
***********************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int operating_system(char *sys) {
FILE *stream;
char *sysptr;
int bit;
sysptr = &sys[0];
sys[0] = 0x0;
stream = popen("/bin/uname -snm", "r");
fread(sysptr, 1, 32, stream);
pclose(stream);
return bit;
}

and$ cat nis.c
/***********************************************
This code returns the machine bit
to the program bitinit
***********************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int operating_sys(char *nis ){
FILE *stream;
char *sysptr;
int bit;
sysptr = &nis[0];
nis[6] = 0x0;
stream=popen("/bin/nisdomainname","r");
fread(sysptr,1,15,stream);
pclose(stream);
return bit;
}

As it is seen this two are doing almost same thing except the unix
command in popen.
is it possible to make it a single routine where the unix command
nisdomainname or uname will be an argument?
 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      04-18-2010
rudra <(E-Mail Removed)> wrote:
> I have 2 subroutine in c(which is ultimately called by fortran):
> $ cat bit_unm.c
> /***********************************************
> This code returns the machine bit
> to the program bitinit
> ***********************************************/
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>


> int operating_system(char *sys) {
> FILE *stream;
> char *sysptr;
> int bit;


This is an uninitialized variable that has some random value.

> sysptr = &sys[0];
> sys[0] = 0x0;


Why do you go through all of this? Using the pointer you
received would do quite well (and setting the first ele-
ment of the array pointed is good for nothing).

> stream = popen("/bin/uname -snm", "r");
> fread(sysptr, 1, 32, stream);


What you read from popen() won't contain a trailing '\0',
so what the caller receives isn't a string (and the caller
has no means of finding out how many characters got read
if the stuff returned by popen() doesn't have a trailing
'\n', e.g. in the case that what '/bin/uname' returnsed
is longer than 32 characters (including the '\n' at the
end). Also please note that popen() (and pclose()) isn't
a standard C function (even though it is declared in
<stdio.h> on POSIX compliant system).

A slightly safer version would be

fscanf( stream, "%31[^\n]", sys );

assuming that what 'sys' points to has enough room for
32 chars. While the result won't contain a trailing '\n'
it will have a '\0', so it's a proper string no matter
what popen() returns.

> pclose(stream);
> return bit;


And here you return the random value 'bit' is set to. What
is that supposed to be good for?

> }


> and$ cat nis.c
> /***********************************************
> This code returns the machine bit
> to the program bitinit
> ***********************************************/
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> int operating_sys(char *nis ){
> FILE *stream;
> char *sysptr;
> int bit;
> sysptr = &nis[0];
> nis[6] = 0x0;


Setting the 7th element of the array to '\0' looks
even more weird than setting the first one in the
other function

> stream=popen("/bin/nisdomainname","r");
> fread(sysptr,1,15,stream);
> pclose(stream);
> return bit;
> }


> As it is seen this two are doing almost same thing except the unix
> command in popen.


Yes, with the difference that what gets returned from
/bin/nisdomainname may have even less characters to give
the caller a chance to figure out what really was returned.

> is it possible to make it a single routine where the unix command
> nisdomainname or uname will be an argument?


Yes, of course, just pass it to popen() as the first argument
instead of the hard-coded string you pass it now (assuming
that the complete command with options is passed to the
function, otherwise you have to either use another string and
do some string-splicing to get the complete command or use
strcmp() to figure out what to call).

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Uno
Guest
Posts: n/a
 
      04-19-2010
Jens Thoms Toerring wrote:
> rudra <(E-Mail Removed)> wrote:
>> I have 2 subroutine in c(which is ultimately called by fortran):
>> $ cat bit_unm.c
>> /***********************************************
>> This code returns the machine bit
>> to the program bitinit
>> ***********************************************/
>> #include <stdlib.h>
>> #include <stdio.h>
>> #include <string.h>

>
>> int operating_system(char *sys) {
>> FILE *stream;
>> char *sysptr;
>> int bit;

>
> This is an uninitialized variable that has some random value.
>
>> sysptr = &sys[0];
>> sys[0] = 0x0;

>
> Why do you go through all of this? Using the pointer you
> received would do quite well (and setting the first ele-
> ment of the array pointed is good for nothing).
>
>> stream = popen("/bin/uname -snm", "r");
>> fread(sysptr, 1, 32, stream);

>
> What you read from popen() won't contain a trailing '\0',
> so what the caller receives isn't a string (and the caller
> has no means of finding out how many characters got read
> if the stuff returned by popen() doesn't have a trailing
> '\n', e.g. in the case that what '/bin/uname' returnsed
> is longer than 32 characters (including the '\n' at the
> end). Also please note that popen() (and pclose()) isn't
> a standard C function (even though it is declared in
> <stdio.h> on POSIX compliant system).
>
> A slightly safer version would be
>
> fscanf( stream, "%31[^\n]", sys );
>
> assuming that what 'sys' points to has enough room for
> 32 chars. While the result won't contain a trailing '\n'
> it will have a '\0', so it's a proper string no matter
> what popen() returns.
>
>> pclose(stream);
>> return bit;

>
> And here you return the random value 'bit' is set to. What
> is that supposed to be good for?
>
>> }

>
>> and$ cat nis.c
>> /***********************************************
>> This code returns the machine bit
>> to the program bitinit
>> ***********************************************/
>> #include <stdlib.h>
>> #include <stdio.h>
>> #include <string.h>
>> int operating_sys(char *nis ){
>> FILE *stream;
>> char *sysptr;
>> int bit;
>> sysptr = &nis[0];
>> nis[6] = 0x0;

>
> Setting the 7th element of the array to '\0' looks
> even more weird than setting the first one in the
> other function
>
>> stream=popen("/bin/nisdomainname","r");
>> fread(sysptr,1,15,stream);
>> pclose(stream);
>> return bit;
>> }

>
>> As it is seen this two are doing almost same thing except the unix
>> command in popen.

>
> Yes, with the difference that what gets returned from
> /bin/nisdomainname may have even less characters to give
> the caller a chance to figure out what really was returned.
>
>> is it possible to make it a single routine where the unix command
>> nisdomainname or uname will be an argument?

>
> Yes, of course, just pass it to popen() as the first argument
> instead of the hard-coded string you pass it now (assuming
> that the complete command with options is passed to the
> function, otherwise you have to either use another string and
> do some string-splicing to get the complete command or use
> strcmp() to figure out what to call).


I thought I'd try to follow along on this one. I don't know what OP
intends, but this was as close as I could come to divining it:

$ gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
$ ./out
sys is Linux dan-desktop i686
$ cat r1.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
FILE *stream;
char *sys;
sys = malloc(100);
stream = popen("/bin/uname -snm", "r");
fscanf( stream, "%31[^\n]", sys );
printf("sys is %s\n", sys);
pclose(stream);
return 0;
}

// gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
$

Question: With this input as an example, what is happening in that
fscanf line?
--
Uno
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      04-19-2010
On 18 Apr, 18:29, rudra <(E-Mail Removed)> wrote:
> I have 2 subroutine in c(which is ultimately called by fortran):
> $ cat bit_unm.c
> /***********************************************
> *This code returns the machine bit
> *to the program bitinit
> ************************************************/
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
>
> int operating_system(char *sys) {
> * * FILE *stream;
> * * char *sysptr;
> * * int bit;
> * * sysptr = &sys[0];
> * * sys[0] = 0x0;
> * * stream = popen("/bin/uname -snm", "r");
> * * fread(sysptr, 1, 32, stream);
> * * pclose(stream);
> * * return bit;
>
> }


bearing Jens's remarks in mind... Is this any help

int operating_system(char *sys, const char *cmd)
{
FILE *stream;
char *sysptr;
int bit;
sysptr = &sys[0];
sys[0] = 0x0;
stream = popen (cmd, "r");
fread (sysptr, 1, 32, stream);
pclose (stream);
return bit;
}


 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      04-19-2010
Uno <(E-Mail Removed)> wrote:
> I thought I'd try to follow along on this one. I don't know what OP
> intends, but this was as close as I could come to divining it:


> $ gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
> $ ./out
> sys is Linux dan-desktop i686
> $ cat r1.c
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>


> int main(void)
> {
> FILE *stream;
> char *sys;
> sys = malloc(100);
> stream = popen("/bin/uname -snm", "r");
> fscanf( stream, "%31[^\n]", sys );
> printf("sys is %s\n", sys);
> pclose(stream);
> return 0;
> }


> // gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra r1.c -o out
> $


> Question: With this input as an example, what is happening in that
> fscanf line?


I guess you mean the "%31[^\n]" bit? It stands for "read up
to 31 characters but stop if you find a '\n' character". A
simple

fscanf( stream, "%31s", sys );

wouldn't do here since it would already stop at the first
white-space character, and of "Linux dan-desktop i686" only
the first word, "Linux", would be read in. By using "[^\n]"
instead of "s" fscanf() is asked to continue reading while
there's no '\n' found in the input - you can specify a set
of characters to accept (or reject when the list starts
with a '^') within the square braces. And the '31' is, of
course, there to keep fscanf() from reading more than 31
chars (the 32nd is the trailing '\0' it automatically ap-
pends). Of course, in your example, where there's room for
100 chars in 'sys' you could use "99[^\n]" instead, but in
the OP's case it looked as if there was only room for 32.

Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Uno
Guest
Posts: n/a
 
      04-19-2010
Nick Keighley wrote:
> On 18 Apr, 18:29, rudra <(E-Mail Removed)> wrote:
>> I have 2 subroutine in c(which is ultimately called by fortran):
>> $ cat bit_unm.c
>> /***********************************************
>> This code returns the machine bit
>> to the program bitinit
>> ***********************************************/
>> #include <stdlib.h>
>> #include <stdio.h>
>> #include <string.h>
>>
>> int operating_system(char *sys) {
>> FILE *stream;
>> char *sysptr;
>> int bit;
>> sysptr = &sys[0];
>> sys[0] = 0x0;
>> stream = popen("/bin/uname -snm", "r");
>> fread(sysptr, 1, 32, stream);
>> pclose(stream);
>> return bit;
>>
>> }

>
> bearing Jens's remarks in mind... Is this any help
>
> int operating_system(char *sys, const char *cmd)
> {
> FILE *stream;
> char *sysptr;
> int bit;
> sysptr = &sys[0];
> sys[0] = 0x0;
> stream = popen (cmd, "r");
> fread (sysptr, 1, 32, stream);
> pclose (stream);
> return bit;
> }
>
>


This might be worse, Nick. He only needs one char *. If anything is
read, then
sys[0] = 0x0;
is overwritten.

The return of bit is guaranteed to have no useful information. The name
of bit is wrong-headed, as what bit is significant in his call to uname,
which you cut out.

What were you intending with cmd?
--
Uno
 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      04-19-2010
Uno <(E-Mail Removed)> wrote:
> Nick Keighley wrote:
> > int operating_system(char *sys, const char *cmd)
> > {
> > FILE *stream;
> > char *sysptr;
> > int bit;
> > sysptr = &sys[0];
> > sys[0] = 0x0;
> > stream = popen (cmd, "r");
> > fread (sysptr, 1, 32, stream);
> > pclose (stream);
> > return bit;
> > }


> This might be worse, Nick. He only needs one char *.


<snip>

> What were you intending with cmd?


Answering the OPs question of

| As it is seen this two are doing almost same thing except the unix
| command in popen.
| is it possible to make it a single routine where the unix command
| nisdomainname or uname will be an argument?

I would presume.
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      04-20-2010
On 19 Apr, 19:52, Uno <(E-Mail Removed)> wrote:
> Nick Keighley wrote:
> > On 18 Apr, 18:29, rudra <(E-Mail Removed)> wrote:


> >> I have 2 subroutine in c(which is ultimately called by fortran):
> >> $ cat bit_unm.c
> >> /***********************************************
> >> *This code returns the machine bit
> >> *to the program bitinit
> >> ************************************************/
> >> #include <stdlib.h>
> >> #include <stdio.h>
> >> #include <string.h>

>
> >> int operating_system(char *sys) {
> >> * * FILE *stream;
> >> * * char *sysptr;
> >> * * int bit;
> >> * * sysptr = &sys[0];
> >> * * sys[0] = 0x0;
> >> * * stream = popen("/bin/uname -snm", "r");
> >> * * fread(sysptr, 1, 32, stream);
> >> * * pclose(stream);
> >> * * return bit;

>
> >> }

>
> > bearing Jens's remarks in mind... Is this any help

>
> > int operating_system(char *sys, const char *cmd)
> > {
> > * * FILE *stream;
> > * * char *sysptr;
> > * * int bit;
> > * * sysptr = &sys[0];
> > * * sys[0] = 0x0;
> > * * stream = popen (cmd, "r");
> > * * fread (sysptr, 1, 32, stream);
> > * * pclose (stream);
> > * * return bit;
> > }


this was done in a hurry as i was about to catch a bus. I passed a
parameter into the original code. I didn't fix all the bugs in the
original code hence "bearing Jens's remarks in mind". To fix the code
properly involved too much mind reading and knowledge of arcane bits
of unix.

> This might be worse, Nick. *


why?


> He only needs one char *. *


I thought system[] was an "out" parameter and cmd[] an "in", to abuse
Ada terminology.

> If anything is read, then
> sys[0] = 0x0;
> is overwritten.
> The return of bit is guaranteed to have no useful information.


this was all covered by Jen's post


>*The name of bit is wrong-headed, as what bit is significant in his call to uname,
> which you cut out.


see excuses section at the beginning


> What were you intending with cmd?


OP:
"is it possible to make it a single routine where the unix command
nisdomainname or uname will be an argument?"


--
"It is a good rule in life never to apologize. The right sort of
people do not want apologies, and the wrong sort take a mean
advantage from them." - P. G. Wodehouse


 
Reply With Quote
 
Uno
Guest
Posts: n/a
 
      04-22-2010
Nick Keighley wrote:


> this was all covered by Jen's post


He's not Jen. He's Jens. I think it's acceptable to create the
possessive as Jens's or Jens', but I'm no English grammarian.

> this was done in a hurry as i was about to catch a bus. I passed a
> parameter into the original code. I didn't fix all the bugs in the
> original code hence "bearing Jens's remarks in mind". To fix the code
> properly involved too much mind reading and knowledge of arcane bits
> of unix.


>> The name of bit is wrong-headed, as what bit is significant in his call to uname,
>> which you cut out.

>
> see excuses section at the beginning


I'm glad you're socially responsible enough to use public
transportation. What makes the long waits bearable? A good fortran, c,
or unix reference book.

rudra never resurfaced, so la dee frickin da. I think that's a little
rude of rudra.
--
Uno
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      04-22-2010
On 22 Apr, 06:55, Uno <(E-Mail Removed)> wrote:
> Nick Keighley wrote:


> > this was all covered by Jen's post

>
> He's not Jen. *He's Jens. *I think it's acceptable to create the
> possessive as Jens's or Jens', but I'm no English grammarian.


you are quite right (and I have no excuses this time). "Jens's" I
believe, "Jens'" if it were a plural.

> *> this was done in a hurry as i was about to catch a bus.


[...]

> I'm glad you're socially responsible enough to use public
> transportation. *What makes the long waits bearable? *A good fortran, c,
> or unix reference book.


Scheme at the moment or downloaded BBC World Service


 
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
use one subroutine's variable value in another subroutine inside a module. king Perl Misc 5 04-29-2007 06:39 AM
Undefined subroutine CGI::Vars Mark Perl 0 07-26-2004 02:13 PM
Subroutine definition Gunnar Hjalmarsson Perl 2 06-17-2004 07:38 PM
Does perl support in/out parameter subroutine? Hon Seng Phuah Perl 1 03-05-2004 03:03 PM
How do I call sort with an anonymous subroutine stored in a hash ?? Casey Perl 3 01-30-2004 03:39 PM



Advertisments