int main(int argc, char *argv[])

The program below does not allow me to enter argv. it goes directly to line 58. How come?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  // Terminating iterations over ranges with iterator sentinals
// we will build an iterator together with a range class,
// which enables us to iterate over a string with unknown lengh, without
// finding the end position in advance
#include <iostream>

// The iterator sentinel is a very central element of this section.
// Its class definition can stay completely empty.
class cstring_iterator_sentinel {};

// Implement the iterator.  It will contain a string pointer, which
// is the container we iterate ove
class cstring_iterator {
    const char *s {nullptr};

public:
	// the constructor initializes the internal string pointer to whatever
	// string the user provides. Let's make the constructor explicit in
	// order to prevent accidental implicit conversion
    explicit cstring_iterator(const char *str)
        : s{str}
    {}

	// when derefercing the iterator at some point, it will just return
	// the character value at this position
	char operator*() const { return *s; }

    // incrementing the iterator just increments the position in the string
	cstring_iterator& operator++() {
        ++s;
        return *this;
    }

	// compare iterators with sentinals
    bool operator!=(const cstring_iterator_sentinel) const {
        return s != nullptr && *s != '\0';
    }
};

// so that a range-base for loop can be used
class cstring_range {
    const char *s {nullptr};

public:
    cstring_range(const char *str)
        : s{str}
    {}

    // return a normal cstring_iterator from the begin function
	cstring_iterator          begin() const { return cstring_iterator{s}; }
	
	// returns a sentinel type
    cstring_iterator_sentinel end()   const { return {}; }
};

int main(int argc, char *argv[])
{
    if (argc != 2) {
        std::cout << "Please provide one parameter.\n";
        return 1;
    }

    const char * const param {argv[1]};

    for (char c : cstring_range(param)) {
        std::cout << c;
    }
	std::cout << '\n';
	
	return 0;
}
Last edited on
closed account (E0p9LyTq)
You can enter command line arguments only when you start your program from a command line. The parameters can't be altered when the program runs.

https://www.tutorialspoint.com/cprogramming/c_command_line_arguments.htm
Does the program actually compile?

Is it reliant on some C++17 feature?
Last edited on
The program below does not allow me to enter argv. it goes directly to line 58. How come?

How did you ran it ?
Have a look at the error messages:
1
2
3
4
5
6
7
8
9
10
11
65:38: error: inconsistent begin/end types in range-based 'for' statement: 'cstring_iterator' and 
'cstring_iterator_sentinel' 

65:38: error: conversion from 'cstring_iterator_sentinel' to non-scalar type 'cstring_iterator' 
requested 

65:38: error: no match for 'operator!=' (operand types are 'cstring_iterator' and 'cstring_iterator') 

65:38: note: candidate is: 35:10: note: bool cstring_iterator::operator!=
(cstring_iterator_sentinel) const 35:10: note: no known conversion for argument 1 from 
'cstring_iterator' to 'cstring_iterator_sentinel'
> Does the program actually compile?

Yes. It requires support for the current standard (C++17).

As of C++17, the types of the begin_expr and the end_expr do not have to be the same, and in fact the type of the end_expr does not have to be an iterator: it just needs to be able to be compared for inequality with one. This makes it possible to delimit a range by a predicate (e.g. "the iterator points at a null character").
http://en.cppreference.com/w/cpp/language/range-for


With C++17 support enabled, compiles (and runs) cleanly with:
g++ 7.3.0 (FreeBSD and MinGW/Windows),
clang++ 5.0.1 (FreeBSD and MinGW/Windows),
g++ 7.2.0 (coliru/Linux) and
Visual Studio 2017 15.5.4 (v141/Windows)

Fails with:
clang++ 3.8.0 (coliru/Linux) and
the clang++ front end v141_clang_c2 (Visual Studio)
Ah yes, you are right. With g++ 6.3.0 (slightly older)
g++ -std=c++17
made it work.

In which case, it actually seems to run fine (from a command prompt).
test.exe Hello!
Hello!
Thank you, all.

I ran the program from the Developer Command Prompt with switches /EHsc /stl:c++17 and an argument for argv. It worked.
I reopened the problem.

Although it worked from the Command Prompt, there must be a way it works from the IDE. Is there a way the argument for argv be inserted through the properties page?
I assume you're talking about Visual Studio 2017?

Right click on your project name in Solution Explorer and select Properties.
Select Debug tab on the left. (Maybe Start Options, depending on the version)
Enter your parameters in Command Line Arguments textbox.
If you are using Visual Studio, in the Project Properties dialog, on the Debugging section you have the "Command arguments" setting, which lets you specify the arguments to pass when debugging the program from the IDE.
Thanks Ganado and helios. Doing the compiling and linking from the IDE is much easier.
Topic archived. No new replies allowed.