Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > newbie-Why does an extra character appear?

Reply
Thread Tools

newbie-Why does an extra character appear?

 
 
Bob
Guest
Posts: n/a
 
      11-27-2005
I was playing with args from command line, trying to understand how
they work. But my little program shows up a strange behaviour that I
don't understand. An extra beginning char appears. For instance where I
expected "abba" I get "aabba" and instead of "tony I get "ttony". Can
someone explain why this is so.
Thanks
Bob

THE PROGRAM
// argtest.c
#include <stdio.h>

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

for (i=0; i<argc; i++) {
printf("argv= %d\n", argv);
printf("argv[0]= %d\n", argv[0]);
printf("*argv= %s\n", *argv);
argv++;
}

char *g;
for(i=0; i<20; i++) {
g = (char*)(4006977+i);
printf(" %c\n", *g);
}
}



THE OUTPUT
C:\kern\find>gcc argtest.c -o argtest

C:\kern\find>argtest abba tony
argv= 4007056
argv[0]= 4006977
*argv= argtest
argv= 4007060
argv[0]= 4006986
*argv= abba
argv= 4007064
argv[0]= 4006992
*argv= tony
a
r
g
t
e
s
t

a
a
b
b
a

t
t
o
n
y

 
Reply With Quote
 
 
 
 
Gordon Burditt
Guest
Posts: n/a
 
      11-27-2005
>I was playing with args from command line, trying to understand how
>they work. But my little program shows up a strange behaviour that I
>don't understand. An extra beginning char appears.


There is no guarantee that the argument strings for argv[] appear
in order or without extra junk in between them. If you look at
memory beyond the end of the argument strings, you have invoked
the wrath of undefined behavior, and you deserve anything you
get (including smegmentation faults).

>For instance where I
>expected "abba" I get "aabba" and instead of "tony I get "ttony".


Don't expect that. You might get "supercalifragilisticexpialidociousabba".

>Can
>someone explain why this is so.
>Thanks
>Bob
>
>THE PROGRAM
>// argtest.c
>#include <stdio.h>
>
>main(int argc, char *argv[])
>{
> int i;
>
> for (i=0; i<argc; i++) {
> printf("argv= %d\n", argv);
> printf("argv[0]= %d\n", argv[0]);
> printf("*argv= %s\n", *argv);
> argv++;
> }
>
> char *g;
> for(i=0; i<20; i++) {
> g = (char*)(4006977+i);


It is a bad idea to hardcode addresses like this into your program.
The address might change on different runs of the same program. In
particular, on some platforms, the argv[] strings go at the top of
the stack (yes, I know C doesn't require a stack, but it doesn't
forbid one either), the address of the *end* of the strings may be
fixed, and the beginning may vary with the length of the strings.

If you mean g = argv[0]+i; , say so.

> printf(" %c\n", *g);
> }
>}
>
>
>
>THE OUTPUT
>C:\kern\find>gcc argtest.c -o argtest
>
>C:\kern\find>argtest abba tony
>argv= 4007056
>argv[0]= 4006977
>*argv= argtest
>argv= 4007060
>argv[0]= 4006986
>*argv= abba
>argv= 4007064
>argv[0]= 4006992
>*argv= tony
> a
> r
> g
> t
> e
> s
> t
>
> a
> a
> b
> b
> a
>
> t
> t
> o
> n
> y
>


Some platforms like to align the argv[] strings on even boundaries,
so this might account for what you are seeing. Try it with arguments
of abba, abba1, abba12, abba123, abba1234, abba12345, etc.

Gordon L. Burditt
 
Reply With Quote
 
 
 
 
Joe Wright
Guest
Posts: n/a
 
      11-28-2005
Bob wrote:
> I was playing with args from command line, trying to understand how
> they work. But my little program shows up a strange behaviour that I
> don't understand. An extra beginning char appears. For instance where I
> expected "abba" I get "aabba" and instead of "tony I get "ttony". Can
> someone explain why this is so.
> Thanks
> Bob
>

Too many errors. I'll attempt the more obvious.

> THE PROGRAM
> // argtest.c
> #include <stdio.h>
>
> main(int argc, char *argv[])
> {
> int i;
>
> for (i=0; i<argc; i++) {
> printf("argv= %d\n", argv);

The type of argv is char**. You can't print it with %d.
> printf("argv[0]= %d\n", argv[0]);

The type of argv[0] is char*. You can't print it with %d.
> printf("*argv= %s\n", *argv);

This has a chance. *argv is a char* and %s is appropriate.
> argv++;
> }
>
> char *g;
> for(i=0; i<20; i++) {
> g = (char*)(4006977+i);

The number 4006977 is bogus.
> printf(" %c\n", *g);
> }
> }
>
>
>
> THE OUTPUT
> C:\kern\find>gcc argtest.c -o argtest
>
> C:\kern\find>argtest abba tony
> argv= 4007056
> argv[0]= 4006977
> *argv= argtest
> argv= 4007060
> argv[0]= 4006986
> *argv= abba
> argv= 4007064
> argv[0]= 4006992
> *argv= tony
> a
> r
> g
> t
> e
> s
> t
>
> a
> a
> b
> b
> a
>
> t
> t
> o
> n
> y
>

Funny, I couldn't get it to compile.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      11-28-2005
On 27 Nov 2005 13:57:57 -0800, "Bob" <(E-Mail Removed)> wrote:

>I was playing with args from command line, trying to understand how
>they work. But my little program shows up a strange behaviour that I
>don't understand. An extra beginning char appears. For instance where I
>expected "abba" I get "aabba" and instead of "tony I get "ttony". Can
>someone explain why this is so.
>Thanks
>Bob
>
>THE PROGRAM
>// argtest.c
>#include <stdio.h>
>
>main(int argc, char *argv[])


Implied return types have been removed from the standard. Use:
int main(...

>{
> int i;
>
> for (i=0; i<argc; i++) {
> printf("argv= %d\n", argv);


If you are going to print pointer values, use %p and cast the value to
a void*.

> printf("argv[0]= %d\n", argv[0]);


You only print argv[0] once. The next time through the loop you print
argv[1]. It would be nice if your message reflected that:
printf("argv[%d]=%p\n", i, (void*)argv[i]);
and delete the increment of argv below.
> printf("*argv= %s\n", *argv);
> argv++;
> }
>
> char *g;


Defining variables after executable statements is not standard before
C99. Don't restrict the number of people who can help you to those
who have a C99 compiler.

> for(i=0; i<20; i++) {
> g = (char*)(4006977+i);
> printf(" %c\n", *g);


You are printing 20 sequential characters beginning with the character
pointed to by argv[0]. You have already established that this string
is only 8 bytes long. Evaluating anything after that invokes
undefined behavior.

You know argv[0] points to 4006977 so that string occupies memory from
4006977 through 4006984. Since argv[1] points to 4006986, 4006985 is
not part of you program interface. Once could say that particular
byte doesn't even belong to your program. The fact that it contains
an 'a' is just a coincidence. (Based on the extra t before tony, I
expect it is an artifact of the way your system processes command
lines.)
> }
>}
>
>
>
>THE OUTPUT
>C:\kern\find>gcc argtest.c -o argtest
>
>C:\kern\find>argtest abba tony
>argv= 4007056
>argv[0]= 4006977
>*argv= argtest
>argv= 4007060
>argv[0]= 4006986
>*argv= abba
>argv= 4007064
>argv[0]= 4006992
>*argv= tony
> a
> r
> g
> t
> e
> s
> t
>
> a
> a
> b
> b
> a
>
> t
> t
> o
> n
> y



<<Remove the del for email>>
 
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
Does return-by-value mean extra copies and extra overhead? mathieu C++ 3 09-04-2009 04:25 PM
Re: extra character when writing file Bartc C Programming 2 04-10-2008 10:26 AM
Weird behavior: fputc adds an extra character. Shafik C Programming 2 02-06-2007 07:27 PM
character encoding +missing character sequence raavi Java 2 03-02-2006 05:01 AM
getting the character code of a character in a string Velvet ASP .Net 9 01-19-2006 09:27 PM



Advertisments