473,406 Members | 2,956 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

argv/pointer problems

Sorry in advance if this is a stupid question - I am new to C++.

In the process of converting program to be run from the command line
into a function to be run from another program I noticed behaviour
that I do not understand. Consider the example programs below:

Program 1 below is a simple program that merely outputs the command
line arguments. This compiles and runs fine with Microsoft Visual C++
6.0 and g++ 3.3.1.

Program 2 brings up a compile time error in both; in MVC++ it is

"test_cline_2.cpp: In function `int main()':
test_cline_2.cpp:19: error: non-lvalue in increment",

and in g++ it is

"test_cline_2.cpp(19) : error C2105: '++' needs l-value".

Program 3 compiles and runs fine.

Can anyone tell me why Program 2 does not compile? A friend has tried
the code on C++ .NET and apparently it *did* compile.

Thanks in advance,

Robin Sanderson

-----

//Program 1
#include <iostream>
using std:: cout; using std::endl;

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

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

-----

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}

void vFunction(int argc, char ** argv)
{
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}
Jul 22 '05 #1
10 2588
Robin Sanderson wrote:
Sorry in advance if this is a stupid question - I am new to C++.

In the process of converting program to be run from the command line
into a function to be run from another program I noticed behaviour
that I do not understand. Consider the example programs below:

Program 1 below is a simple program that merely outputs the command
line arguments. This compiles and runs fine with Microsoft Visual C++
6.0 and g++ 3.3.1.

Program 2 brings up a compile time error in both; in MVC++ it is

"test_cline_2.cpp: In function `int main()':
test_cline_2.cpp:19: error: non-lvalue in increment",

and in g++ it is

"test_cline_2.cpp(19) : error C2105: '++' needs l-value".

Program 3 compiles and runs fine.

Can anyone tell me why Program 2 does not compile? A friend has tried
the code on C++ .NET and apparently it *did* compile.

Thanks in advance,

Robin Sanderson

-----

//Program 1
#include <iostream>
using std:: cout; using std::endl;

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

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}
In this program, argv is a pointer.

-----

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}
In this program, argv is an array. You can't increment an array.
-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}

void vFunction(int argc, char ** argv)
{
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}


Here, argv is again a pointer.

--
2 hours? Boy, that's way too old. You should use a more recent version.
(Waldo Bastian about a copile error in a 2 hours old CVS version of KDE)

Jul 22 '05 #2
Thanks, Rolf. Can anyone explain why the code runs on .NET?
Jul 22 '05 #3
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3? Is it possible to declare argv as a pointer
in Program 2 (so it can be used in an identical way as in the other
programs)?

Thanks,

Robin

-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}
void vFunction(int argc, char * argv[]) {
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}

Jul 22 '05 #4
Robin Sanderson wrote:
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3?
In program 3, it's a parameter, while in program 2, it's a local
variable. You cannot pass arrays as parameters to functions, and
therefore, a "convenience" was added to C (and inherited to C++). If
you write a parameter in a form that looks like an array, it will
actually be a pointer. That's btw the reason why you can leave out the
size. When defining an array, you _always_ need a size for it.
Is it possible to declare argv as a pointer in Program 2 (so it can be
used in an identical way as in the other programs)?

int main()
{
int i;

int argc=3;
char * args[3];

args[0] = "program_name";
args[1] = "argument_1";
args[2] = "argument_2";

char * (*argv) = args;
// declares argv as a pointer to the array args

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

Jul 22 '05 #5

"Robin Sanderson" <ro*************@orange.net> wrote in message
news:3a**************************@posting.google.c om...
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3?
The first is an array, the second is a pointer. Even though you say char*
argv[], it is a pointer. Using [] in a function parameter is just another
way of declaring a pointer (in other words [] is a lie, it looks like an
array but it isn't). There is no way to have an array as a function
parameter. So the real difference is that in one case argv is a function
parameter (no arrays allowed) and in the second case argv is a local
variable (arrays are allowed).
Is it possible to declare argv as a pointer
in Program 2 (so it can be used in an identical way as in the other
programs)?


Sure, one way would be

int argc=3;
char * argv_array[3];
char ** argv = argv_array;

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

john
Jul 22 '05 #6
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

argv is of type char* const. You can't change it's value.


char * argv[3];

char * pCurrent = argv;

pCurrent++;

-JKop
Jul 22 '05 #7
JKop posted:
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl; argv++; }

return 0;
}

argv is of type char* const. You can't change it's value.


char * argv[3];

char * pCurrent = argv;

pCurrent++;


OOPS!!!!

char ** pCurrent = argv;

-JKop
Jul 22 '05 #8
JKop wrote:
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

argv is of type char* const.


No, it isn't. it's of type array of type char* with 3 elements.

Jul 22 '05 #9
Thanks Rolf and John for your clear explanations. I have to admit I
still don't understand why Program 2 compiled and ran on .NET, but
otherwise I am starting to get the hang of this C++ pointer-malarkey.

Thanks again,

Robin
Jul 22 '05 #10
JKop <NU**@NULL.NULL> wrote:
Robin Sanderson posted:
int main()
{
int i;

int argc=3;
char * argv[3];

argv is of type char* const. You can't change it's value.

No, argv's type is " array[3] of char* ". When used in an expression
like argv++ it is equivalent to &argv[0], which has type " char ** ".
There is no "const" anywhere. argv is a non-modifiable lvalue (which
is a distinct concept from "const"). Another example of a non-modifiable
lvalue is the address of a builtin type; the following code won't
compile for the same reason:
int x;
++ &x;
or
(&x) = 0;
Jul 22 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: Bret | last post by:
I'm curious why char** argv is acceptable in the main() declaration. In the comp.lang.c FAQ (question 6.18) it says that pointers to pointers and pointers to an array are not interchangable. ...
28
by: Charles Sullivan | last post by:
I'm working on a program which has a "tree" of command line arguments, i.e., myprogram level1 ]] such that there can be more than one level2 argument for each level1 argument and more than one...
5
by: jab3 | last post by:
(again :)) Hello everyone. I'll ask this even at risk of being accused of not researching adequately. My question (before longer reasoning) is: How does declaring (or defining, whatever) a...
2
by: ais523 | last post by:
I've been wondering about the compatibility of pointers to signed, unsigned and plain char, and it's not clear to me how interchangeable they are. Is the following portable? int main(int argc,...
5
by: jerry | last post by:
I need to modify the code of a command-line tool. The source code starts out like this: int main(int argc, char *argv) { int ch, A, B ; while ((ch = getopt(argc, argv, "AB")) != -1)...
11
by: vicky | last post by:
hi all, please tell me with example, how the *argv point to the the no of strings.
24
by: Logan | last post by:
Why (I) works but (II) gives segmentation error? (I) int main(int argc, char *argv) { printf("%s", argv); } (II) int main(int argc, char *argv) { printf("%s", argv);
2
by: Joe Wright | last post by:
candide wrote: Nope. It is most correctly 'char **argv', pointer to pointer to char. Declaring 'char *argv' is exactly equivalent. It says argv is an array of pointers to char. Expressing argv...
12
by: kevin.eugene08 | last post by:
Hello all, Forgive the somewhat simple question I am sure this will be, but I am having some problem understanding what: char **argv looks like. For instance, i know through trial and error...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.