Strange ARGC/ARGV Behaviour

X

Xog Blog

Hi

I am by some people's standards a newbie to C, and I
am refreshing my memory as to some of its conventions. I would
like any patient soul out there to help out.

I am having a horrible time figuring out argc/argv in a C
program I am writing. I need a program to extract integers and
print the ASCII representations of them. Here is the source of
this very short program under Linux:

#include <stdio.h>
#include <strings.h>

int main (int argc, char *argv[]) {
/* this only takes a number as an argument */
int num = 0;
int count = argc;
for (; (count > 0); count--) {
num = strtol(argv[count]);
printf ("%d\t", count);
printf ("%d\t'%c'\n", num, num);
}
return 0;
}

Here is the command line with the parameters:

$ ascii 97 98 99 100 101

Here is the output of the program:

6 0 ''
5 101 'e'
4 0 ''
3 99 'c'
2 0 ''
1 97 'a'

So, there is a "magic" sixth parameter that appears out of
nowhere. In addition, only every second ascii character is
interpreted. What is interesting is that I get a segfault if I
substitute the two printf's with the line:

printf ("%d\t%d\t'%c'\n", count, num, num);

Paul King
 
F

fan_c

Your count should start from argc - 1 . i.e 5 in this case.

Just so u r clear ...

argc[0] == ascii
argc[1] == 97
....
....
argc[5] == 101

---cheers!
 
C

Christopher Benson-Manica

Xog Blog said:
#include <stdio.h>
#include <strings.h>

This header doesn't exist, nor do you need the one that does exist,
int main (int argc, char *argv[]) {
int num = 0;
int count = argc;

Wrong. Arrays in C are zero-indexed; the highest index of argv is
argc-1, as the previous poster pointed out.
for (; (count > 0); count--) {
num = strtol(argv[count]);

Again wrong. strtol takes three arguments; it's a wonder that gcc
(presumably your compiler, given that you are using Linux) accepted
it. It isn't a wonder that your program doesn't work.

<ot>
man strtol and do yourself a favor and invoke gcc thus:

gcc -Wall -ansi -pedantic
printf ("%d\t", count);
printf ("%d\t'%c'\n", num, num);

It's a pedant's point, but %c is intended for a character, and you've
passed it an integer.
 
L

Lawrence Kirby


....
It's a pedant's point, but %c is intended for a character, and you've
passed it an integer.

It outputs the argumnt as a character. However %c is specified as taking
an int argument. This isn't suprising as a char argument given in a
variable argument list will be promoted to int (or rarely unsigned
int) before being passed. int can be a reasonable type to hold a character
value, e.g. the return type of getc() and argument type of the various
functions in <ctype.h> is int.

Lawrence
 
E

Emmanuel Delahaye

Xog Blog wrote on 20/09/05 :
I am by some people's standards a newbie to C, and I
am refreshing my memory as to some of its conventions. I would
like any patient soul out there to help out.

I am having a horrible time figuring out argc/argv in a C
program I am writing. I need a program to extract integers and
print the ASCII representations of them. Here is the source of
this very short program under Linux:

#include <stdio.h>
#include <strings.h>

not standard. You meant

#include <string.h>

but it is useless here.
int main (int argc, char *argv[]) {
/* this only takes a number as an argument */
int num = 0;
int count = argc;
for (; (count > 0); count--) {
num = strtol(argv[count]);

Missing <stdlib.h>
Missing parameters.
argv[argc] = NULL by definition.
The decreasing loop is tricky. Dou you really want to start from the
end ?
printf ("%d\t", count);
printf ("%d\t'%c'\n", num, num);
}
return 0;
}

Here is the command line with the parameters:

$ ascii 97 98 99 100 101

Here is the output of the program:

6 0 ''
5 101 'e'
4 0 ''
3 99 'c'
2 0 ''
1 97 'a'

So, there is a "magic" sixth parameter that appears out of
nowhere. In addition, only every second ascii character is
interpreted. What is interesting is that I get a segfault if I
substitute the two printf's with the line:

printf ("%d\t%d\t'%c'\n", count, num, num);

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
/* this only takes a number as an argument */
int num = 0;
int count = argc - 1;

for (; (count > 0); count--)
{
num = strtol (argv[count], NULL, 10);
printf ("%d\t", count);
printf ("%d\t'%c'\n", num, num);
}
return 0;
}

5 101 'e'
4 100 'd'
3 99 'c'
2 98 'b'
1 97 'a'

No magic !

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"It's specified. But anyone who writes code like that should be
transmogrified into earthworms and fed to ducks." -- Chris Dollin CLC
 

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,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top