Jump to content
  • Advertisement
Sign in to follow this  
TheBinaryMan

Double pointer to argv

This topic is 2830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. Im still not comfortable working with pointers when arrays and strings are involved, so hopefully clarification will help. If I have the following code:


char **p_argv;

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

for(int i=0;i<argc;i++)
cout << (*p_argv) << endl;
}



If I use "(*p_argv)" to dereference one level, I get the beginning char for each string in argv. How do I access the rest of the chars for each of the strings?

Share this post


Link to post
Share on other sites
Advertisement
There are a couple way about doing this. Since you are using C++, I'd say go the "safe" route below. But if you want to do this the classic C way to learn how C style strings are used, go the "unsafe" way.


#include <string>
#include <iostream>

#include <cstring>

int main(int argc, char *argv[])
{
// The safe way
for(int i=0; i < argc; ++i)
{
const std::string arg = argv;
std::cout << arg << std::endl;

//this
const std::string::size_type length = arg.length();
for( int j = 0; j < length; ++j )
std::cout << arg[j] << std::endl;

//or better yet, this:
for( std::string::const_iterator itr = arg.begin(); itr != arg.end(); ++itr )
std::cout << *itr << std::endl;
}

// The unsafe way
for(int i=0; i < argc; ++i)
{
const char *arg = argv;
std::cout << arg << std::endl;
const size_t length = strlen(arg);
for( int j = 0; j < length; ++j )
std::cout << arg[j] << std::endl;
}
}






I say one is safe and the other isn't because direct pointer manipulation can quickly lead to bugs if you are unsure what you are doing. Try not to use C style strings in C++ code. Use std::string whereever you can.

Share this post


Link to post
Share on other sites
Quote:
Original post by TheBinaryMan
If I use "(*p_argv)" to dereference one level, I get the beginning char for each string in argv. How do I access the rest of the chars for each of the strings?

You are "dereferencing" two levels. one with x and one with *x.

x[0] is the same as *x

(*p_argv) is the same as p_argv[0]

Just write p_argv to get the whole string

Share this post


Link to post
Share on other sites
char* argv[] is a variable named argv of type char* [].*

What is that type? It's an array (hence []) of char*.

So, argv[i] gives us element #i of the array. Each element is a char*.

Supplying a char* to std::cout::operator<< prints the pointed-at string.

Now, how about *argv[i]? That is taking argv[i], which is a char*, and dereferencing it, using the '*'. Dereferencing a char* gives us a char - the one that the pointer is pointing at.

When a char* is used to represent a string, it points at the beginning of the string (which is assumed to just run until the next zero byte). Thus, dereferencing the char* yields the beginning character of the string.

Supplying a char to std::cout::operator<< prints the character.

* This is actually a lie. Because the array size isn't known before we run the program, we can't specify it, and therefore this isn't really an array. The type is actually char**. But we will be using it the same way.

Incidentally, "the array size isn't known before we run the program" is why we need the argc parameter. :)




As for KulSeran's advice, I'd take it a little further:


#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <ostream>

int main(int argc, char* argv[]) {
// First, since both arrays and C-style strings cause problems, let's
// replace both with real first-class types:
std::vector<std::string> args(argv, argv + argc);

// Let's use the standard library to display the strings on separate lines:
std::copy(args.begin(), args.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

// And just for show: we can, of course, feed the input directly to std::copy:
std::copy(argv, argv + argc, std::ostream_iterator<char*>(std::cout, "\n"));
}



C++ is a very different language from C. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!