0

I recently started learning C++. I come from a background of python and web development so bear that in mind.

I wanted to write a program which takes a second argument which is an integer and does stuff. But then it started acting crazy and I realized this was a problem with casting. So I wrote this:

int main(int argc, char** argv) {
    int iMynum = int(argv[1]);
    cout << argv[1] << endl;
    cout << iMynum << endl;
    return 0;
};

running myprogram 100 results in:

100
3429646

I don't understand this. I found similar questions on SO but the answers were complicated and confused me even more. I tried doing this instead:

int iMynum = (int) *argv[1];

Which resulted in:

100
49

What is going on here?

update

Obviously, I'm an idiot - int(argv[1]) is python. So the answers really helped me understand what I was doing, but suggested code solution did not work (except for atoi which I take is not recommended). I kept looking and tried this:

into mynum = const_cast<int>(argv[1][0])

And got an error saying const_cast cannot convert 'char' to 'int'. So what should I use instead?

yuvi
  • 18,155
  • 8
  • 56
  • 93
  • 2
    `argv[1]` is a pointer (to the first character in the string `"100"` in this case). Cast a pointer to an `int`, and you get the numeric value of the address of the thing being pointed to. – Oliver Charlesworth Dec 31 '13 at 02:10
  • Where did you learn this `int(argv[1]);`? – Fiddling Bits Dec 31 '13 at 02:13
  • @prmottajr: That is a dreadfully useless tag. – Lightness Races in Orbit Dec 31 '13 at 02:17
  • 1
    Well, that just goes to show, even if you're really good at Thing A, that doesn't mean you get to be good at Thing B by just angrily shouting at it. You'll still need to learn it, like the rest of us. – Kerrek SB Dec 31 '13 at 02:17
  • @FiddlingBits I'm piecing it together based on an old book and the internet. I just now found a reference to `const_cast<…>` but I'm still confused by it – yuvi Dec 31 '13 at 02:17
  • 49 is the int value of '1' according to ascii, the first digit of '100' -- start by looking at `atoi` - then look at how to do that in more standard C++ – Glenn Teitelbaum Dec 31 '13 at 02:17
  • @FiddlingBits: Apparently because in python you turn a string to int with `int()`. – Siyuan Ren Dec 31 '13 at 02:18
  • Basically this means that python and c/c++ are vastly different. You need to learn the basics before starting to use it. – Siyuan Ren Dec 31 '13 at 02:19
  • @FiddlingBits also, emberessing, I just realized that I was basically getting it from python – yuvi Dec 31 '13 at 02:32
  • @C.R. I am. C++ basics are confusing – yuvi Dec 31 '13 at 02:33
  • @KerresSB I know it's a tough transition, obviously. I don't know why I left such a "I think it's easy" impression. I don't. I think working with argv is a very basic and important tool to have with a language that requires re-compiling for every small change (with argv you can build functions and test them easily without compiling every time. It's a good way to learn about optimization which I understand is a crucial part of C++ programming) – yuvi Dec 31 '13 at 02:38
  • 1
    `const_cast(argv[1][0])` is totally off. I don't know where you saw that but it's clear that you're guessing. **Please learn C++ from [a proper book](http://stackoverflow.com/q/388242/560648).** Good luck! – Lightness Races in Orbit Dec 31 '13 at 05:10
  • @RacesInOrbit from an old book alright... thanks for the link, I'll check it out – yuvi Dec 31 '13 at 10:15
  • 1
    @yuvi: I think the post has since been edited :-) This doesn't really have anything to do with `argv`: It's simply that interpreting a string as a number under some representation is a high-level business-logic operation on dynamic data. There's no more a way this could be part of the C *language* than, say, a webserver could be. The type system and object model of C are so vastly different from those of Python that I was surprised that you would pick on *one* keyword that existed in both languages and find yourself upset that it has different meanings. And +1 to LRiO's suggestion above. – Kerrek SB Dec 31 '13 at 11:52

4 Answers4

5

You seem to be trying to obtain an int from a string like "123" by simply casting a char-pointer — which contains only a memory address! — into an integer.

That's not how it works. Casts are tools of the static type system, not magical runtime data transformers. You have to parse the string.

There are plenty of questions on Stack Overflow about parsing strings (even C-strings like yours) into integers. For example, you can use a std::stringstream, boost::lexical_cast, std::strtol or (in C++11) std::stoi.

I leave it up to you to go and research this topic, now that you know what mistake you made and what to look for next.


Here's what I'd do:

#include <iostream>
#include <cassert>
#include <boost/lexical_cast.hpp>

int main(int argc, char** argv)
{
    assert(argc >= 2);
    const int iMynum = boost::lexical_cast<int>(argv[1]);

    std::cout << argv[1] << '\n';
    std::cout << iMynum << '\n';
};
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • You're explanation is wonderful but I'm not being able to recreate you're code solution - 1. I don't have boost (or don't know how to add it... remember I'm still fighting with the basics) 2. Assert doesn't work at all 3. Using `std::string stream(argv[1]);` gives me a `type 'into' unexpected` error – yuvi Dec 31 '13 at 02:28
  • In plain C you can simple use `strtol`: `long mynum=strtol(argv[1], 0, 0)`. – Siyuan Ren Dec 31 '13 at 02:38
  • @yuvi You have a typo, do `stream` not `stream` – Nick Garvey Dec 31 '13 at 02:46
  • @NickGarvey That's my phone's annoying autocorrect, I don't have it in my code, it ain't the problem – yuvi Dec 31 '13 at 02:53
  • @yuvi: `Using std::string stream(argv[1]); gives me a type 'int' unexpected error` That's because you wrote "string stream", not "stringstream" which is what I told you. And you can't just swap `boost::lexical_cast` for `std::stringstream` in your code and expect it to magically work. They are different things. What documentation did you look up after reading my answer? As I wrote, "there are plenty of questions on Stack Overflow about parsing strings" — please take the opportunity now to look them up. – Lightness Races in Orbit Dec 31 '13 at 05:05
  • The space is a typo in the comment, I didn't use a space... never mind, I'll look it up. Thank you for all your help! – yuvi Dec 31 '13 at 10:16
2

arg[1] is char* type and the string will be output.

(int)arg[1] only return the address of the parameter, so you will get the address.

roalz
  • 2,699
  • 3
  • 25
  • 42
  • So what should I do instead? – yuvi Dec 31 '13 at 02:43
  • To answer your second question, int iMynum = (int) *argv[1]; Here arg[1] is char* type, which value "100", so *argv[1] should be the char type same with first character: '1'. int iMynum = (int) *argv[1] will convert char '1' to int value which has ascii code 49. – user3138096 Dec 31 '13 at 06:10
  • 1
    @user3138096: The OP never said that his execution character set was ASCII; nor does the choice of character set *matter*, and it should not pollute the mind of the innocent. – Kerrek SB Dec 31 '13 at 11:53
1

The input parameter is a string array which was stored in char*, when you get arg[1], it just return the string array (char*), if you output it, the whole string will be output. But if you convert it ot string, it just convert the memory address of the parameter to int, so you will just see the address result.

roalz
  • 2,699
  • 3
  • 25
  • 42
Alix Dong
  • 220
  • 2
  • 11
0

To parse an int from the argument list, you want to use atoi() which is defined in stdlib.h

int iMynum = atoi(argv[1]);

You should also check that argv is at least length 2 before hand.

Lokno
  • 590
  • 3
  • 15