fgetc

0

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" .
 
V

Vladimir Oka

01 said:
#include <stdio.h>

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.
 
0

01

01 said:
#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?
 
L

lovecreatesbeauty

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

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
 
R

Richard Heathfield

lovecreatesbeauty said:
int main ( int argc, char *argv[] )
{
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.
 
P

pete

lovecreatesbeauty said:
int main ( int argc, char *argv[] )
{
printf( "usage: %s filename", argv[0] );

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.
 
0

01

Richard said:
lovecreatesbeauty said:
int main ( int argc, char *argv[] )
{
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?
 
P

pete

01 said:
Richard said:
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;
}
 
R

Richard Heathfield

01 said:
Richard said:
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[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.
 
0

01

Richard said:
01 said:
Richard said:
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[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.
 
0

01

Richard said:
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?
 
P

pete

[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.
 
L

lovecreatesbeauty

pete said:
lovecreatesbeauty said:
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"?

lovecreatesbeauty
 
L

lovecreatesbeauty

Richard said:
lovecreatesbeauty said:
01 said:
int main ( int argc, char *argv[] )
{
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
 
P

pete

lovecreatesbeauty said:
lovecreatesbeauty said:
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
 
R

Richard Heathfield

lovecreatesbeauty said:

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.
 
P

pete

lovecreatesbeauty said:
Richard said:
lovecreatesbeauty said:
01 wrote:
int main ( int argc, char *argv[] )
{
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 **))
 
N

Nick Keighley

01 said:
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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Command Line Arguments 0
Why can't use fgetc() in SWITCH with CASE? 15
getc fgetc 7
Working with files 1
How can I view / open / render / display a pdf file with c code? 0
C pipe 1
comparison error 12
Text processing 29

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top