By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,655 Members | 1,005 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

fgetc

P: n/a
01
#include <stdio.h>

int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );

/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
unsigned char x;
/* read one character at a time from file, stopping at EOF,
which
indicates the end of the file. Note that the idiom of
"assign
to a variable, check the value" used below works because
the assignment statement evaluates to the value
assigned. */
while ( ( x = fgetc( file ) ) != EOF )
{
printf( "%c", x );
}
}
fclose( file );
}
}
this program doesnt work. when i type the program name and following a
file name, it clear the screen and display nothing. where was wrong ?
and i am not sure about the function "fgetc" .

Jun 27 '06 #1
Share this Question
Share on Google+
37 Replies


P: n/a

01 wrote:
#include <stdio.h>
<snip>
else
{
unsigned char x;
/* read one character at a time from file, stopping at EOF, which
indicates the end of the file. Note that the idiom of "assign
to a variable, check the value" used below works because
the assignment statement evaluates to the value assigned. */
while ( ( x = fgetc( file ) ) != EOF )
{
printf( "%c", x );
}
}
fclose( file );
}
}
this program doesnt work. when i type the program name and following a
file name, it clear the screen and display nothing. where was wrong ?
and i am not sure about the function "fgetc" .


Function `fgetc` returns an `int`, and you're forcing it into `unsigned
char`. As EOF is guaranteed to be negative, your `while` will run
forever. The screen does not actually go blank, but filled with
"blanks" issued by `printf()` (actually, whatever EOF happens to be
once forced into `unsigned char`). You're actually (un)lucky it does,
as without terminating '\n', `printf()` may not produce any output.

Change `x` to `int`, and try again.

Jun 27 '06 #2

P: n/a
01
oh, thank you for your help , it work now, thanx
Vladimir Oka wrote:

Function `fgetc` returns an `int`, and you're forcing it into `unsigned
char`. As EOF is guaranteed to be negative, your `while` will run
forever. The screen does not actually go blank, but filled with
"blanks" issued by `printf()` (actually, whatever EOF happens to be
once forced into `unsigned char`). You're actually (un)lucky it does,
as without terminating '\n', `printf()` may not produce any output.

Change `x` to `int`, and try again.


Jun 27 '06 #3

P: n/a
01

01 wrote:
oh, thank you for your help , it work now, thanx
Vladimir Oka wrote:

Function `fgetc` returns an `int`, and you're forcing it into `unsigned
char`. As EOF is guaranteed to be negative, your `while` will run
forever. The screen does not actually go blank, but filled with
"blanks" issued by `printf()` (actually, whatever EOF happens to be
once forced into `unsigned char`). You're actually (un)lucky it does,
as without terminating '\n', `printf()` may not produce any output.

Change `x` to `int`, and try again.

oh, sorry to top-post,

Jun 27 '06 #4

P: n/a
01

01 wrote:
#include <stdio.h>

int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );

/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
unsigned char x;
/* read one character at a time from file, stopping at EOF,
which
indicates the end of the file. Note that the idiom of
"assign
to a variable, check the value" used below works because
the assignment statement evaluates to the value
assigned. */
while ( ( x = fgetc( file ) ) != EOF )
{
printf( "%c", x );
}
}
fclose( file );
}
}

..
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,so argv[0] is a char, then how can it hold the the whole program
name?

Jun 27 '06 #5

P: n/a

01 wrote:
int main ( int argc, char *argv[] )
{
<snip>
printf( "usage: %s filename", argv[0] );

<snip>
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,
it is a wrong expression.
so argv[0] is a char, then how can it hold the the whole program
name?


argv is declared as array of pointer to char. argv[0] is a pointer to
the first character of the program name.

lovecreatesbeauty

Jun 27 '06 #6

P: n/a
lovecreatesbeauty said:

01 wrote:
> int main ( int argc, char *argv[] )
> {

<snip>
so argv[0] is a char, then how can it hold the the whole program
name?
argv is declared as array of pointer to char.


No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to p.
(No, this does not mean that arrays and pointers are the same thing, which
they are not. If they were, I would not be bothering to distinguish between
them.)
argv[0] is a pointer to
the first character of the program name.


Not necessarily. It may be NULL. As for "program name", what that actually
means is not something you can trust your weight to. For example, it might
be a text representation of a pid.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 27 '06 #7

P: n/a
lovecreatesbeauty wrote:

01 wrote:
int main ( int argc, char *argv[] )
{
<snip>
printf( "usage: %s filename", argv[0] );
<snip>
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,


it is a wrong expression.


There's nothing wrong with it.
so argv[0] is a char, then how can it hold the the whole program
name?


argv is declared as array of pointer to char. argv[0] is a pointer to
the first character of the program name.


That's how a pointer to a string works.

--
pete
Jun 27 '06 #8

P: n/a
01

Richard Heathfield wrote:
lovecreatesbeauty said:

01 wrote:
> int main ( int argc, char *argv[] )
> {

<snip>
so argv[0] is a char, then how can it hold the the whole program
name?


argv is declared as array of pointer to char.


No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to p.
(No, this does not mean that arrays and pointers are the same thing, which
they are not. If they were, I would not be bothering to distinguish between
them.)
argv[0] is a pointer to
the first character of the program name.


Not necessarily. It may be NULL. As for "program name", what that actually
means is not something you can trust your weight to. For example, it might
be a text representation of a pid.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

argv[] is an array that contains many pointers.argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?

so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.
why not use printf("%s", *argv[0]) to print the real stuff?

Jun 27 '06 #9

P: n/a
01 wrote:

Richard Heathfield wrote:
lovecreatesbeauty said:
argv is declared as array of pointer to char.
No, it's declared (and defined) as a pointer to pointer to char.
The []
notation is a misleading hangover from primaeval C.
In the context of a
formal parameter list, T *p and T p[] have the same meaning
- pointer to p.
(No, this does not mean that arrays and
pointers are the same thing, which they are not.
If they were,
I would not be bothering to distinguish between them.)

argv[] is an array that contains many pointers.
argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?


Not exactly.
The type of argv is (char **).
The value of (sizeof argv) won't varry as argc varries.

#include <stdio.h>

int main (int argc, char *argv[])
{
printf("sizeof argv is %lu\n", (long unsigned)sizeof argv);
return 0;
}

--
pete
Jun 27 '06 #10

P: n/a
01 said:

Richard Heathfield wrote:
lovecreatesbeauty said:
<snip>
>
> argv is declared as array of pointer to char.
No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to
p. (No, this does not mean that arrays and pointers are the same thing,
which they are not. If they were, I would not be bothering to distinguish
between them.)
> argv[0] is a pointer to
> the first character of the program name.


Not necessarily. It may be NULL. As for "program name", what that
actually means is not something you can trust your weight to. For
example, it might be a text representation of a pid.


argv[] is an array


No, it isn't. I already explained this. It is a pointer to the first element
in an array. It is possible to prove this from the Standard, but you may
find K&R pp99-100 rather simpler to follow:

"As formal parameters in a function definition,

char s[];

and

char *s;

are equivalent; we prefer the latter because it says more explicitly that
the parameter is a pointer."

(The base type here is irrelevant - they could just as easily have written T
p[] and T *p, and T could certainly be char *.)

See also Dennis Ritchie's page on a couple of early C compilers:

<http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html>

which says in part:

"Neither compiler yet handled the general declaration syntax of today or
even K&R I, with its compound declarators like the one in int **ipp; . The
compilers have not yet evolved the notion of compounding of type
constructors ("array of pointers to functions", for example). These would
appear, though, by 5th or 6th edition Unix (say 1975), as described (in
Postscript) in the C manual a couple of years after these versions.

"Instead, pointer declarations were written in the style int ip[];. A fossil
from this era survives even in modern C, where the notation can be used in
declarations of arguments. On the other hand, the later of the two does
accept the * notation, even though it doesn't use it. (Evolving compilers
written in their own language are careful not to take advantage of their
own latest features.)"

that contains many pointers.argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?
Not necessarily. If argc is 0, then argv[0] will be NULL. And even if argc >
0, argv[0]'s representation of the program name will not necessarily be in
a form that allows you to execute the program.

so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.
No, if argc is > 0 the call will print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.
why not use printf("%s", *argv[0]) to print the real stuff?


Because argv[0] is a char *, so *argv[0] is a single char, and passing a
single char to printf to match a %s format specifier invokes undefined
behaviour.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 27 '06 #11

P: n/a
01

Richard Heathfield wrote:
01 said:

Richard Heathfield wrote:
lovecreatesbeauty said:
<snip> >
> argv is declared as array of pointer to char.

No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to
p. (No, this does not mean that arrays and pointers are the same thing,
which they are not. If they were, I would not be bothering to distinguish
between them.)

> argv[0] is a pointer to
> the first character of the program name.

Not necessarily. It may be NULL. As for "program name", what that
actually means is not something you can trust your weight to. For
example, it might be a text representation of a pid.


argv[] is an array


No, it isn't. I already explained this. It is a pointer to the first element
in an array. It is possible to prove this from the Standard, but you may
find K&R pp99-100 rather simpler to follow:

"As formal parameters in a function definition,

char s[];

and

char *s;

are equivalent; we prefer the latter because it says more explicitly that
the parameter is a pointer."

(The base type here is irrelevant - they could just as easily have written T
p[] and T *p, and T could certainly be char *.)

See also Dennis Ritchie's page on a couple of early C compilers:

<http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html>

which says in part:

"Neither compiler yet handled the general declaration syntax of today or
even K&R I, with its compound declarators like the one in int **ipp; . The
compilers have not yet evolved the notion of compounding of type
constructors ("array of pointers to functions", for example). These would
appear, though, by 5th or 6th edition Unix (say 1975), as described (in
Postscript) in the C manual a couple of years after these versions.

"Instead, pointer declarations were written in the style int ip[];. A fossil
from this era survives even in modern C, where the notation can be used in
declarations of arguments. On the other hand, the later of the two does
accept the * notation, even though it doesn't use it. (Evolving compilers
written in their own language are careful not to take advantage of their
own latest features.)"

that contains many pointers.argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?


Not necessarily. If argc is 0, then argv[0] will be NULL. And even if argc >
0, argv[0]'s representation of the program name will not necessarily be in
a form that allows you to execute the program.

so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.


No, if argc is > 0 the call will print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.
why not use printf("%s", *argv[0]) to print the real stuff?


Because argv[0] is a char *, so *argv[0] is a single char, and passing a
single char to printf to match a %s format specifier invokes undefined
behaviour.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


extremly, consider a program named only one char,a, for example.
printf("%s", argv[0]) it works.
printf("%c",argv[0]) it doesnt work.
printf("%c",*argv[0]) it works.

so how to explain that?
thank you for your patience.

Jun 27 '06 #12

P: n/a
01

Richard Heathfield wrote:
so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.


No, if argc is > 0 the call will print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.

so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?

Jun 27 '06 #13

P: n/a
01 wrote:
Richard Heathfield wrote:
01 said:
Richard Heathfield wrote:
[perfect explanation with references snipped,
because you don't seem to be reading it]
argv[] is an array
No, it isn't. I already explained this.

extremly, consider a program named only one char,a, for example.
printf("%s", argv[0]) it works.
printf("%c",argv[0]) it doesnt work.
printf("%c",*argv[0]) it works.

so how to explain that?
thank you for your patience.


printf("%c",**argv) it works.

*argv[0] in a expression context,
means the exact same thing as **argv.

*argv[] in a parameter context
means the exact same thing as **argv.

--
pete
Jun 27 '06 #14

P: n/a
pete wrote:
lovecreatesbeauty wrote:

01 wrote:
> int main ( int argc, char *argv[] )

<snip>
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,

it is a wrong expression.

There's nothing wrong with it.


Is an identifier plus a pair of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?

lovecreatesbeauty

Jun 27 '06 #15

P: n/a

Richard Heathfield wrote:
lovecreatesbeauty said:
01 wrote:
> int main ( int argc, char *argv[] )
> { <snip> so argv[0] is a char, then how can it hold the the whole program
name?

argv is declared as array of pointer to char.

No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to p.
(No, this does not mean that arrays and pointers are the same thing, which
they are not. If they were, I would not be bothering to distinguish between
them.)


int main ( int argc, char *argv[] )
{
char *a2[argc];
/*...*/

I think a2 has the same meaning of argv. They all are array of pointer
to char. The corresponding argument to argv acts as a pointer to
pointer to char inside the function body, but a2 which has the same
declaration sequence is still an array of pointer to char.

lovecreatesbeauty

Jun 27 '06 #16

P: n/a
lovecreatesbeauty wrote:

pete wrote:
lovecreatesbeauty wrote:

01 wrote:
> > int main ( int argc, char *argv[] )
<snip>
> printf( "usage: %s filename", argv[0] ); argv[] is a char
> array,
it is a wrong expression.

There's nothing wrong with it.


Is an identifier plus a pair of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?


Your terminology needs work.

The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]
char *argv[]
is a parameter declaration, not an expression,
and in a parameter declaration context
char *argv[]
means the exact same thing as
char **argv

--
pete
Jun 27 '06 #17

P: n/a
lovecreatesbeauty said:

<snip>
int main ( int argc, char *argv[] )
{
char *a2[argc];
/*...*/

I think a2 has the same meaning of argv.
Then you think wrong, as I've explained twice already.

In your example code, argv has type char **, whereas a2 in C90 violates a
constraint, and in C99 has type char *[argc]. These are different types.
They all are array of pointer to char.


Not so.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 27 '06 #18

P: n/a
lovecreatesbeauty wrote:

Richard Heathfield wrote:
lovecreatesbeauty said:
01 wrote:
> > int main ( int argc, char *argv[] )
> > {

<snip>
> so argv[0] is a char, then how can it hold the the whole program
> name?
argv is declared as array of pointer to char.

No, it's declared (and defined) as a pointer to pointer to char. The []
notation is a misleading hangover from primaeval C. In the context of a
formal parameter list, T *p and T p[] have the same meaning - pointer to p.
(No, this does not mean that arrays and pointers are the same thing, which
they are not. If they were, I would not be bothering to distinguish between
them.)


int main ( int argc, char *argv[] )
{
char *a2[argc];
/*...*/

I think a2 has the same meaning of argv. They all are array of pointer
to char.


No.

sizeof a2 equals (argc * sizeof (char *))
sizeof argv equals (sizeof (char **))

--
pete
Jun 27 '06 #19

P: n/a
01 wrote:
Richard Heathfield wrote:

so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.


No, if argc is > 0 the call will print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.


so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?


so do you mean why not something like this:-

char *cp = argv[0];
while (cp != '\0')
{
printf ("%c", *cp);
cp++;
}

because it's more code?
--
Nick keighley

Jun 27 '06 #20

P: n/a
pete wrote:

lovecreatesbeauty wrote:

pete wrote:
lovecreatesbeauty wrote:
>
> 01 wrote:
> > > int main ( int argc, char *argv[] )
> <snip>
> > printf( "usage: %s filename", argv[0] ); argv[] is a char
> > array,
> it is a wrong expression.
There's nothing wrong with it.
Is an identifier plus a pair
of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?


Your terminology needs work.

The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]


.... and there's also another expression
in the expression statement.

char *argv[]
is a parameter declaration, not an expression,
and in a parameter declaration context
char *argv[]
means the exact same thing as
char **argv

--
pete
Jun 27 '06 #21

P: n/a
01 wrote:

Richard Heathfield wrote:
so printf("%s", argv[0])
would print the contents of argv[0] which is
a pointer.


No, if argc is > 0 the call will
print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.


so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?


Because argv[0] itself,
is a pointer and may or may not contain null characters,
and it certainly isn't supposed to be considered as a string.

--
pete
Jun 27 '06 #22

P: n/a
On Tue, 27 Jun 2006 15:04:55 UTC, "lovecreatesbeauty"
<lo***************@gmail.com> wrote:
pete wrote:
lovecreatesbeauty wrote:

01 wrote:
> > int main ( int argc, char *argv[] )
<snip>
> printf( "usage: %s filename", argv[0] ); argv[] is a char
> array,
it is a wrong expression.

There's nothing wrong with it.


Is an identifier plus a pair of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?


Learn to read a declaration like a C compiler does:

*argv[]

argv a variable
*argv a pointer to a variable
*argv[] an array of pointers to variables
* has higher presendce than [], so its an array of pointers
*(argv[]) a pointer to an array
() has higher presedence than *, so it is pointer to an
array.

**argv a pointer to a pointer to a variable
syntactical the same as *argv[]

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Jun 27 '06 #23

P: n/a
Herbert Rosenau wrote:
On Tue, 27 Jun 2006 15:04:55 UTC, "lovecreatesbeauty"
<lo***************@gmail.com> wrote:
pete wrote:
lovecreatesbeauty wrote:
> 01 wrote:
> > > int main ( int argc, char *argv[] ) > it is a wrong expression.
There's nothing wrong with it.
Is an identifier plus a pair of square brackets
of subscript operator lacking of subscription valid?
If it is correct, what does "argv[]" mean?
Is it the same as "argv"?

*argv[] an array of pointers to variables


Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).

Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

--
pete
Jun 27 '06 #24

P: n/a
"01" <fi********@126.com> writes:
[...]
argv[] is an array that contains many pointers.argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?
I think this may be where you go wrong.

What do you mean when you write "argv[]"? What are the empty square
brackets supposed to mean? argv[], with the empty square brackets, is
not a legal expression (it may appear in some declarations, but we'll
leave that aside).

(We sometimes informally refer to a function named "func" as "func()"
to emphasize the fact that it's a function. We don't usually do this
for arrays.)

Given:

int main(int argc, char *argv[]) { /* ... */ }

there is an object (specifically a parameter) whose name is argv. It
is of type pointer-to-pointer-to-char. In spite of the [] syntax, no
array is declared here; in this context, "char *argv[]" means exactly
the same thing as "char **argv".

So argv is a pointer-to-pointer-to-char; it points to a
pointer-to-char. That pointer-to-char is (probably) the first element
of an array of several pointers-to-char; that array will have been
created at execution time by the environment before it invokes the
main program.

So argv is an expression, the name of an object, and its type is
pointer-to-pointer-to-char.

That means that *argv, or equivalently argv[0], is an expression of
type pointer-to-char; if argv is non-null, then *argv is a pointer to
the first character of a string containing some representation of the
program name.
so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.
No. argv[0] is a pointer to char; it happens to point (probably) to
the first character of a string. printf() with "%s" doesn't print the
contents of the pointer; it prints the string that the pointer points
to. (More precisely, the pointer points to the first character of the
string, but the standard defines "pointing to a string" to mean
"pointing to the first character of a string".)
why not use printf("%s", *argv[0]) to print the real stuff?


Because it's illegal (actually it invokes undefined behavior).
argv[0] is a pointer-to-char, so *argv[0] (it groups as *(argv[0])) is
an expression of type char. It's probably the first character of the
program name. So this attempts to print just the first character of
the program name, but since it uses the wrong format, it won't work.

This:
printf("%c", *argv[0]);
or, equivalently:
printf("%c", **argv);
or, equivalently:
printf("%c", argv[0][0]);
or, equivalently:
putchar(**argv);
prints the first character of the program name.

I suggest reading section 6 of the comp.lang.c FAQ, at
<http://www.c-faq.com/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 27 '06 #25

P: n/a

pete wrote:
pete wrote:
lovecreatesbeauty wrote:
pete wrote:
> lovecreatesbeauty wrote:
> > 01 wrote:
> > > > int main ( int argc, char *argv[] )
> > > printf( "usage: %s filename", argv[0] ); argv[] is a char
> > > array,
> > it is a wrong expression.
> There's nothing wrong with it.
Is an identifier plus a pair
of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?

Your terminology needs work.
The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]

... and there's also another expression
in the expression statement.


And one more you missed, as Keith Thompson pointed out later that an
illegal expression is not a legal expression.

lovecreatesbeauty

Jun 28 '06 #26

P: n/a
On 2006-06-27, Nick Keighley <ni******************@hotmail.com> wrote:
01 wrote:
Richard Heathfield wrote:

> > so printf("%s", argv[0]) would print the contents of argv[0] which is
> > a pointer.
>
> No, if argc is > 0 the call will print a sequence of characters starting at
> the address stored in argv[0] and ending at the first null character
> encountered. If argc is 0, the behaviour is undefined.


so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?


so do you mean why not something like this:-

char *cp = argv[0];
while (cp != '\0')
{
printf ("%c", *cp);
cp++;
}

because it's more code?


Yes, it's more code. And it's confusing and useless.

if (argv[0])
puts (argv[0]);

is much cleaner and is likely a lot more efficient.

Also, your while loop should be (*cp != '\0'), with the star. If that wasn't
a typo, you should think about why it should be what it should be.

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 28 '06 #27

P: n/a
lovecreatesbeauty wrote:

pete wrote:
pete wrote:
lovecreatesbeauty wrote:
> pete wrote:
> > lovecreatesbeauty wrote:
> > > 01 wrote:
> > > > > int main ( int argc, char *argv[] )
> > > > printf( "usage: %s filename", argv[0] );
> > > > argv[] is a char array,
> > > it is a wrong expression. Your terminology needs work.
The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]

... and there's also another expression
in the expression statement.


And one more you missed, as Keith Thompson pointed out later that an
illegal expression is not a legal expression.


Are you talking about the code, or his comment,
"argv[] is a char array"?
There's no illegal expression in the shown code.

N869
5.1.2.2.1 Program startup
[#1] The function called at program startup is named main.
The implementation declares no prototype for this function.
It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv,
though any names may be used, as they are local to the
function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;8) or in some other implementation-defined
manner.

8) Thus, int can be replaced by a typedef name defined as
int, or the type of argv can be written as char ** argv,
and so on.

--
pete
Jun 28 '06 #28

P: n/a
On Tue, 27 Jun 2006 20:49:34 UTC, pete <pf*****@mindspring.com> wrote:
Herbert Rosenau wrote:
On Tue, 27 Jun 2006 15:04:55 UTC, "lovecreatesbeauty"
<lo***************@gmail.com> wrote:
pete wrote:
> lovecreatesbeauty wrote:
> > 01 wrote:
> > > > int main ( int argc, char *argv[] ) > it is a wrong expression.
> There's nothing wrong with it.

Is an identifier plus a pair of square brackets
of subscript operator lacking of subscription valid?
If it is correct, what does "argv[]" mean?
Is it the same as "argv"?
*argv[] an array of pointers to variables


Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).


What is exactly the same as *argv[].

In a definition you can't left [] empty - in a declaration you can and
you would.

By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.


Come on, tell us why in an parameter declaration *argv[] should be
wrong.

You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array
**a a pointer to a pointer

That is inependant of the number of elements in an array. When the
number is empty it is only a declaration - if not it can be a
definition.

That has absolutely nothjing to do if it is a parameter, an argument
or a declaration ([])/definition [<numer>]. It is primitive sytax.

long *a[] a declaration of an pointer to an array of pointers
as an argument, a formal parameter, on file scope or
static.

int **a a pointer to a pointer independant of it is an argument,
a formal parameter, on file scope or static.

Learn the presedence of operators and you can interpret it right.

Don't reference to Richard for that. You knows what he tells you.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Jun 28 '06 #29

P: n/a
Herbert Rosenau wrote:

On Tue, 27 Jun 2006 20:49:34 UTC, pete <pf*****@mindspring.com> wrote:
Herbert Rosenau wrote:
On Tue, 27 Jun 2006 15:04:55 UTC, "lovecreatesbeauty"
<lo***************@gmail.com> wrote:
> pete wrote:
> > lovecreatesbeauty wrote:
> > > 01 wrote:
> > > > > int main ( int argc, char *argv[] )
> > > it is a wrong expression.
> > There's nothing wrong with it.
>
> Is an identifier plus a pair of square brackets
> of subscript operator lacking of subscription valid?
> If it is correct, what does "argv[]" mean?
> Is it the same as "argv"?

*argv[] an array of pointers to variables


Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).


What is exactly the same as *argv[].

In a definition you can't left [] empty


char string[] = "You can leave [] empty in a defintion."
- in a declaration you can and you would.

By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.


You have me quoted above, as taking the opposite point.
> > There's nothing wrong with it.


You have to learn how a standard conforming compier reads *a[].


You have to learn how to be coherent.

--
pete
Jun 28 '06 #30

P: n/a
Herbert Rosenau said:
On Tue, 27 Jun 2006 20:49:34 UTC, pete <pf*****@mindspring.com> wrote:
<snip>

The type of the argv parameter in main, is (char **).


What is exactly the same as *argv[].


Right. And pete knows that.
In a definition you can't left [] empty - in a declaration you can and
you would.
Pete knows that too.

<snip>
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.


He isn't saying it's wrong. He's saying it is not declaring an array of
pointers.
You have to learn how a standard conforming compier reads *a[].
<snip>
*a[] a pointer to an array of pointers


Not true in the parameter context that we are discussing. T *arg[] in a
parameter context means that arg has type T **.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 28 '06 #31

P: n/a
Richard Heathfield wrote:

Herbert Rosenau said:

In a definition you can't left [] empty
- in a declaration you can and you would.


Pete knows that too.


char string[] = "I know about some of that";

--
pete
Jun 28 '06 #32

P: n/a
pete said:
Richard Heathfield wrote:

Herbert Rosenau said:

> In a definition you can't left [] empty
> - in a declaration you can and you would.


Pete knows that too.


char string[] = "I know about some of that";


Fair cop, guv. Herbert was, of course, thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 28 '06 #33

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.de> writes:
On Tue, 27 Jun 2006 20:49:34 UTC, pete <pf*****@mindspring.com> wrote: [...]
The type of the argv parameter in main, is (char **).


What is exactly the same as *argv[].


Yes, in that particular context.
In a definition you can't left [] empty - in a declaration you can and
you would.
pete already showed a counterexample.
By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.
Both
int main(int argc, char *argv[])
and
int main(int argc, char **argv)
are perfectly correct, and they're precisely equivalent. I don't
think anyone here has stated otherwise. Personally, I prefer the
latter form because it's more explicit; the former depends on a
special-case rule that, though it's enshrined in the language
definition, I don't particularly like because of the potential
confusion. (There's no real confusion if you actually understand it,
of course.)
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.


Come on, tell us why in an parameter declaration *argv[] should be
wrong.


It isn't.
You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array
**a a pointer to a pointern

That is inependant of the number of elements in an array. When the
number is empty it is only a declaration - if not it can be a
definition.

That has absolutely nothjing to do if it is a parameter, an argument
or a declaration ([])/definition [<numer>]. It is primitive sytax.


No, it has *everything* to do with whether it's a parameter.

There is a special rule that applies only to parameter declarations.
It says that, in a parameter declaration, and only in a parameter
declaration, this:
int foo[]
really means this:
int *foo

The rule is C99 6.7.5.3p7:

A declaration of a parameter as "array of type" shall be adjusted
to "qualified pointer to type", where the type qualifiers (if any)
are those specified within the [ and ] of the array type
derivation.

The intent of
int foo[]
is that foo *should* be a pointer to the first element of an array,
but it's up to the caller to create that array and arrange for foo to
point to its first element. The caller isn't even required to do so.

Consider this program:

#include <stdio.h>

static void func(int param[])
{
if (param == NULL) {
printf("param = NULL\n");
}
else {
printf("param != NULL\n");
}
printf("sizeof param = %d\n", (int)sizeof(param));
}

int main(void)
{
func(NULL);
return 0;
}

It's perfectly legal. param is a pointer, not an array. The
reference to the value of param inside func() does not invoke the
conversion of an array expression to a pointer, because it's already a
pointer. There is no array in sight (other than the string literals).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 28 '06 #34

P: n/a
Richard Heathfield wrote:

pete said:
Richard Heathfield wrote:

Herbert Rosenau said:

> In a definition you can't left [] empty
> - in a declaration you can and you would.

Pete knows that too.


char string[] = "I know about some of that";


Fair cop, guv. Herbert was, of course,
thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!


I am actually unable to sum the total number of times that
we've explained the same thing over and over in this thread.
Keith Thompson is also on this thread now.
Both of you guys are much better at explaining C, than I am.
I can't take this thread anymore.
Good luck to both of you and whoever may join you!

--
pete
Jun 28 '06 #35

P: n/a
In article <wm***************************@JUPITER1.PC-ROSENAU.DE>
Herbert Rosenau <os****@pc-rosenau.de> wrote:
You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable
These two are correct by themselves, but:
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array
these two are wrong. The "[]" subscript operator binds more tightly
than the unary "*" indirection operator, and this applies to
declarators as well. So:

int *p[10];

defines an array of 10 elements, each element having type "int *".
So does:

int *(p[10]);

You have to write:

int (*p)[10];

to define a single pointer, pointing to an array of 10 "int"s.
**a a pointer to a pointer
This one is correct.
long *a[] a declaration of an pointer to an array of pointers
as an argument, a formal parameter, on file scope or
static.


If you write:

long *a[];

int main(void) {
...
}

then "a" really has type "array 1 of pointer to long". The reason
the array has size 1 is slighty complicated, having to do with
tentative definitions. If you rewrite the declaration line to
read:

extern long *a[];

then "a" really has type "array (of unknown size) of pointer to
long". It is not a pointer to an array of pointers, nor is it a
pointer to an array of "long"s, but rather an array -- of some
size, unspecified at the point of the declaration -- of "long".

But -- there is always a "but" in C :-) -- there *is* a special
case here, involving parameter declarations. The C99 draft I keep
handy says, for instance, in section 6.7.1:

[#10] On entry to the function all size expressions of its
variably modified parameters are evaluated, and the value of
each argument expression shall be converted to the type of
its corresponding parameter, as if by assignment to the
parameter. Array expressions and function designators as
arguments are converted to pointers before the call. A
declaration of a parameter as ``array of type'' shall be
adjusted to ``pointer to type,'' and a declaration of a
parameter as ``function returning type'' shall be adjusted
to ``pointer to function returning type,'' as in 6.2.2.1.
The resulting parameter type shall be an object type.

Thus, in a function prototype or function definition (6.7.1 is
about definitions), if we write:

void f(int arg[100]) {
/* code */
}

the formal parameter (arg) "obviously" has type "array 100 of int",
but *actually* has type "pointer to int". The size -- 100 -- is
dropped entirely (except, in C99, if it is marked with the "static"
keyword, or uses the new variable length array gimmicks).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.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.
Jun 29 '06 #36

P: n/a
On Wed, 28 Jun 2006 22:26:05 UTC, Richard Heathfield
<in*****@invalid.invalid> wrote:
pete said:
Richard Heathfield wrote:

Herbert Rosenau said:

> In a definition you can't left [] empty
> - in a declaration you can and you would.

Pete knows that too.


char string[] = "I know about some of that";


Fair cop, guv. Herbert was, of course, thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!

I'm not a native english speaker. I had learned english in german pubs
by scottish peoples and mostenly by reading english comuter scinse
books. Sometimes it is easy for me to misunderstund idiomatic
expressions.

I started programming where I was 20 years old on a computer that was
only available of 12 decimal digit words, programming business
applications, going to native 8 bit assembler, over fortran 77 to
RTL2, high level macroassembler, programming human live dependant
technical applications in C, programming an realtime OS using an
defective K&R C compiler who was really unable to build char pointers
right (casts to/from char pointer ends up with illegal result). Years
later I learned ANSI C 89 and how to write strictly conforming
applications to run them under highly different OSes. On my employers
I'm known as notorious pedant as I don't like careless mistakes in
programming.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Jun 29 '06 #37

P: n/a
Herbert Rosenau (in
wm***************************@JUPITER1.PC-ROSENAU.DE) said:

| I'm not a native english speaker. I had learned english in german
| pubs by scottish peoples and mostenly by reading english comuter
| scinse books. Sometimes it is easy for me to misunderstund idiomatic
| expressions.

Your English is more than adequate - I'd be proud of myself if I spoke
any second language as well as you speak English. FWIW, it's not
unusual for native speakers to occasionally have difficulty with
idiomatic expressions.

| I'm known as notorious pedant as I don't like careless
| mistakes in programming.

You're known that way here, too. :-D

Please don't change - I've learned much from you.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Jun 29 '06 #38

This discussion thread is closed

Replies have been disabled for this discussion.