Yet another pointer related problem

S

sugaray

The purpose of the following program is to store all the
arguments passed to main() into an array of char, and print'em out
onto the screen.

#include <stdio.h>

int main (int argc, char **argv)
{
int i;
char buffer[1024];
char *pb = buffer;

if (argc == 1)
exit (1);

for (i = 1; i < argc; ++i)
{
while (*argv != '\0')
*pb++ = *argv++;
*pb++ = ' ';
}
*pb = '\0';

printf ("%s\n", buffer);

return 0;
}

but when I tried to modify the string manipulation process
only using pointer arithmetic as below, I got stucked and
can't figure out why. probably I'm still got hazy about the
concept of pointer. hope you can help me out, thanx.

for(;argc>1;--argc)
{
while(*++*argv != '\0')
*pb++ = **argv++;
*pb++ = ' ';
}
 
V

Vijay Kumar R Zanvar

sugaray said:
The purpose of the following program is to store all the
arguments passed to main() into an array of char, and print'em out
onto the screen.

#include <stdio.h>

int main (int argc, char **argv)
{
int i;
char buffer[1024];

You don't need this when you have argv with you!
char *pb = buffer;

if (argc == 1)
exit (1);

for (i = 1; i < argc; ++i)
{
while (*argv != '\0')
*pb++ = *argv++;
*pb++ = ' ';
}
*pb = '\0';

printf ("%s\n", buffer);

return 0;
}

but when I tried to modify the string manipulation process
only using pointer arithmetic as below, I got stucked and
can't figure out why. probably I'm still got hazy about the
concept of pointer. hope you can help me out, thanx.

for(;argc>1;--argc)
{
while(*++*argv != '\0')
*pb++ = **argv++;
*pb++ = ' ';
}


F:\Vijay\c> type argc.c
#include <stdio.h>
#include <stdlib.h>

int
main ( int argc, char *argv[] )
{
puts ( "The output:" );
while ( argc-- )
{
while ( **argv )
putchar ( *(*argv)++ );
putchar ( ' ' );
*argv++;
}
return EXIT_SUCCESS;
}

F:\Vijay\c>gcc -Wall argc.c
F:\Vijay\c>a.exe 1 2 3 vijay
The output:
f:/vijay/c/a.exe 1 2 3 vijay
 
G

Grumble

sugaray said:
The purpose of the following program is to store all the arguments
passed to main() into an array of char, and print'em out onto the
screen.

#include <stdio.h>

int main(int argc, char **argv)
{
char **p;

for (p = argv; *p != NULL; ++p) puts(*p);

return 0;
}

or

#include <stdio.h>

int main(int argc, char **argv)
{
int i;

for (i=0; i < argc; ++i) puts(argv);

return 0;
}
 
D

Dan Pop

In said:
sugaray said:
The purpose of the following program is to store all the arguments
passed to main() into an array of char, and print'em out onto the
screen.

#include <stdio.h>

int main(int argc, char **argv)
{
char **p;

for (p = argv; *p != NULL; ++p) puts(*p);

return 0;
}

or

#include <stdio.h>

int main(int argc, char **argv)
{
int i;

for (i=0; i < argc; ++i) puts(argv);

return 0;
}


Two examples of wasteful programs that can be combined into an
environmentally friendly one:

#include <stdio.h>

int main(int argc, char **argv)
{
while (*argv) puts(*argv++);
return 0;
}

Dan :)

P.S. This example and the canonical strcpy loop are at the limit of
what I consider readable C code. People who don't understand them
cannot consider themselves C programmers and people who abhor them
are likely to never like C.
 
R

Richard Bos

for(;argc>1;--argc)
{
while(*++*argv != '\0')

You can modify argv, because it's a function parameter. You can also
modify argv[x][y] and friends, because argv[x] point to writable memory.
But you cannot modify argv[x], because the pointers in argv themselves
are (or at least, are allowed to be) constant. From the Standard:

# The parameters argc and argv and the strings pointed to by the argv
# array shall be modifiable by the program,

and note that nothing is said about argv's members themselves being
modifiable, only about the strings they point to.

Therefore,

++*argv

is not correct.

Richard
 
C

CBFalconer

Dan said:
.... snip ...

Two examples of wasteful programs that can be combined into an
environmentally friendly one:

#include <stdio.h>

int main(int argc, char **argv)
{
while (*argv) puts(*argv++);
return 0;
}

My version, which reverses the display order:

#include <stdio.h>
int main(int argc, char** argv) {
while (argc--) puts(argv[argc]);
return 0;
}

Both evince the clarity of using while in place of for. These are
actually useful when suspicious of the argument passing
mechanisms, such as layers of scripts and shells.
 
D

Dan Pop

In said:
[email protected] (sugaray) said:
for(;argc>1;--argc)
{
while(*++*argv != '\0')

You can modify argv, because it's a function parameter. You can also
modify argv[x][y] and friends, because argv[x] point to writable memory.
But you cannot modify argv[x], because the pointers in argv themselves
are (or at least, are allowed to be) constant. From the Standard:

# The parameters argc and argv and the strings pointed to by the argv
# array shall be modifiable by the program,

and note that nothing is said about argv's members themselves being
modifiable, only about the strings they point to.

Therefore,

++*argv

is not correct.

However, even Kernighan got it wrong, when he wrote *++argv[0] in the
example at page 117. Is it mentioned in the K&R2 errata?

Dan
 
C

- CASE -

All supplied examples, although correct, don't
generate the originally intended output.
Dan Pop wrote:

... snip ...
Two examples of wasteful programs that can be combined into an
environmentally friendly one:

#include <stdio.h>

int main(int argc, char **argv)
{
while (*argv) puts(*argv++);
return 0;
}


My version, which reverses the display order:

#include <stdio.h>
int main(int argc, char** argv) {
while (argc--) puts(argv[argc]);
return 0;
}

Both evince the clarity of using while in place of for. These are
actually useful when suspicious of the argument passing
mechanisms, such as layers of scripts and shells.
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top