1

Firstly, I know my title looks like a commonly asked question, but hear me out. When I say 'Parsing arguments' I don't mean the command line arguments that get passed to the program when it starts up. I'm trying to create a seperate system to receive commands and parse them in runtime.

Main:

int main(int argc, char *args[])
{
    cout << "Started up." << endl;
    reloop();
}
// Main execution point. Prints text to the console and moves to a void:

void reloop()
{
    char *str;
    cin >> str;
    parseargs(str);
}
// Starts waiting for inputted data, if found, move onto parseargs void.

void parseargs(char *args)
{
    char *strings[10];
    char delim[] = " ";
    int i = 0;
    strings[i] = strtok(args,delim);

    if(strings[0] == "try")
    {
        cout << "WORKED!" << endl;
        reloop();
    }
    else
    {
        cout << "Na. Didn't work." << endl;
        reloop();
    }
}
// Takes the arguments passed to it, splits them via a space and passes them to an array. From here, compares the first entry in the array to a command. If they equal, output success note.

Now, I'm a C# programmer for quite some time and have only just started C++.. What am I doing wrong? When the program starts up, an error comes up with:

Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll
File: c:\program files\microsoft visual studio 11.0\vc\include\istream
Line: 990
Expression: Invalid null pointer

*Note: I do have declarations for each function at the top of the CPP file.

6502
  • 112,025
  • 15
  • 165
  • 265
Daaksin
  • 834
  • 3
  • 13
  • 28
  • 2
    And you can't compare `char*` strings using `==`. Use `strcmp()` or look at `std::string`. Does `cin >> char*` actually work? There is no memory allocated unless cin does it for you. Looks suss to me! And then there is the stack. Your stack keeps getting bigger and bigger each time the parse fails... – John3136 Aug 05 '13 at 06:40
  • You have of course narrowed the problem down to the line that causes the error, right? – JJJ Aug 05 '13 at 06:42
  • Don't use tabs to format code here on SO next time – 6502 Aug 05 '13 at 06:45
  • @YuHao: It's none of these. It's in the `` header. – Benjamin Lindley Aug 05 '13 at 06:45
  • None of the `strings` pointers have any allocated memory. Why use `char *`s anyway? Also, you'll only ever pass in one word to `parseargs` if you get rid of the UB. – chris Aug 05 '13 at 06:46
  • @John3136 Oh! What about the stack getting bigger!? What do I have to do to stop it? – Daaksin Aug 05 '13 at 06:49
  • @chris Alright thanks, and what do you mean by UB? – Daaksin Aug 05 '13 at 06:50
  • @chris How can I go about passing more than one words? Where can I find documentation on this sort of thing? – Daaksin Aug 05 '13 at 07:36
  • `std::cin >>` stops at whitespace. `std::getline` reads a line. The reference I use is http://en.cppreference.com/w/cpp – chris Aug 05 '13 at 07:41
  • Cheers Chris, this is pretty much exactly what I need! – Daaksin Aug 05 '13 at 07:44
  • @Daaksin re: stack `reloop()` calls `parseargs()` which calls `reloop()` which calls `parseargs()` and so on until you run out of stack. You need to refactor so that one method returns before calling the other - e.g. return an error code or something. – John3136 Aug 05 '13 at 11:32

4 Answers4

3

One bug I can find in your code is in function void reloop()

char *str;
cin >> str;   <---"Undefined behavior"

You don't allocate memory for str.

correct it either:

  1. char str[SIZE];
  2. Dynamically allocate space: char* str = new char[SIZE];

Next error is:

if(strings[0] == "try")

should be:

if(strcmp( strings[0], "try")!=0)
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • @Daaksin your welcome! remember dynamically allocated memory has to delete explicitly using `delete`. read about it. – Grijesh Chauhan Aug 05 '13 at 06:56
  • Wow, that's a new thing hahaha. Thanks again! – Daaksin Aug 05 '13 at 06:58
  • @Daaksin Check it [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Grijesh Chauhan Aug 05 '13 at 07:00
  • 2
    @Daaksin, Even better, don't use `new` and `delete`. Switch to something like `std::string`. – chris Aug 05 '13 at 07:10
  • @chris Yes better approach indeed, but Daaksin's code looks more like a C code instead of C++, So I didn't suggest. – Grijesh Chauhan Aug 05 '13 at 07:12
  • The only problem with using std::string is that most of the functions require the char *str way of doing it. And there's no quick way to convert to string like there is in Python or C#, as far as I know... – Daaksin Aug 05 '13 at 07:39
1
   void reloop() {
     char *str; /* WRONG */
     cin >> str;
     parseargs(str);
   }

You should have written it that way :

   void reloop() {
     char str[BUF_MAX]; /* ok but take care of buffer overflow; maybe use std::string */
     cin >> str;
     parseargs(str);
   }
phaazon
  • 1,972
  • 15
  • 21
1

Even if you know C# please note that you don't know anything about C++ and that even if you're very smart intuition will guide you down the wrong path (actually especially if you're very smart: C++ in quite a few parts is indeed "illogical" so a logic mind is not going to help at all).

The reason is that C++ is the way it is for a mix of complex reasons, including committee effect and a lot of historical heritage. No matter how smart you are you're not going to guess neither history nor what a committee decided.

How char * are part of C++ is one of these things that can only be understood if you know history (especially history of C). The error in you program is that you cannot write

char *str;
cin >> str;

because you didn't allocate the memory for it. It would also be bad code because potentially overflows the memory you allocate. If you're missing this then you're going to miss a LOT of other much more subtle points of C++ programming.

Do yourself a favor and start by reading cover-to-cover a good C++ book instead of just experimenting with a compiler.

Experimenting is not a reasonable path with C++ because of its very complex and sometimes illogical structure and because of "undefined behaviour" that means that when doing a mistake you cannot count on a clear error message but can get crazy behaviour instead (including the most dangerous crazy behaviour... i.e. the code apparently will work anyway even when a mistake is present).

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265
0

Your code problem has been explained by others.

There is one more general problem with your code: you are not using existing functions or libraries which would do what you need.

Pure C solution: http://www.gnu.org/software/libc/manual/html_node/Getopt.html

C++ Boost program options: http://www.boost.org/doc/libs/1_54_0/doc/html/program_options.html

Dariusz
  • 21,561
  • 9
  • 74
  • 114