C++ exam, who gets the first one correct? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the proper declaration of main?
I just attended my first c++ exam.
First question was
int main(◊, char ** argv)
Which one of the following suggestions will not work (as first formal parameter substitute for ◊):
a) char argc
b) int argc
c) double argc
d) bool argc
The answer counts 2% in a 4 hour purely handwritten individual exam.
All tools are allowed, accept any programmable device or any means of communication
Who can get this right :)?

Define what "works" means. Any of those might work, but a valid, standard-compliant, well-formed C++ program has either of the following signatures:
int main()
int main(int argc, char** argv)
int main(int argc, char* argv[])
So a), c) and d) are wrong.

Define "will not work" ?
int main(char argc, char ** argv)
{
printf("%d\n", argc);
return 0;
}
./a.out 1 2 3
Output: 4
int main(int argc, char ** argv)
{
printf("%d\n", argc);
return 0;
}
./a.out 1 2 3
Output: 4
int main(double argc, char ** argv)
{
printf("%d\n", *(int*)&argc);
return 0;
}
./a.out 1 2 3
Output: 4
int main(bool argc, char ** argv)
{
printf("%d\n", argc);
return 0;
}
./a.out 1 2 3
Output: 4

Given that the question is asking which one will not work. It would have to be double all the others are integers.
I believe this would be the correct answer because you can't index an array with anything other than an integral value. But that assumes that you actually want to index the argv array.
But what a bad question to ask on a C++ exam.

"int argc" is the correct usage. argc represents the number of parameters passed to the main. So its only int.

Related

Looping through array using pointers

The following program in C++ prints more output than I expected. Can anyone explain why this has happened? The program attempts to use pointers to loop through the integer array, printing each value along the way.
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
puts("hi");
int ia[5] = {1,2,3,4,5};
for (int *p = ia; *p; ++p) {
printf("Char is: %d\n", *p);
}
return 0;
}
/*
hi
Char is: 1
Char is: 2
Char is: 3
Char is: 4
Char is: 5
Char is: 32767
Char is: -811990796
Char is: -133728064
Char is: 1606416320
Char is: 32767
Char is: -1052593579
Char is: 32767
Program ended with exit code: 0
*/
You will need to have a 0/NULL value to stop at, currently you do not.
Your loop condition will allow iteration until you get a value that evaluates to false (i.e 0) and your array does not contain that, so your iteration will continue on past the bounds of the array and will at some point exit when it access some memory its not supposed to.
There are several ways to fix it. You can add a 0 to the end of the array.
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
puts("hi");
int ia[] = {1,2,3,4,5, 0};
for (int *p = ia; *p; ++p) {
printf("Char is: %d\n", *p);
}
return 0;
}
Issue with this is that you now cant use 0 in your array, or it will terminate early.
A better way would be to pre calculate the address at which to stop, given the array length. This address is one off the end of the array.
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
puts("hi");
int ia[] = {1,2,3,4,5};
int* end = ia + 5;
for (int *p = ia; p != end; ++p) {
printf("Char is: %d\n", *p);
}
return 0;
}
Now we are getting towards the method used by standard library iterators. Now templates can deduce the size of the array.
i.e.
#include <iterator>
...
for (auto it = std::begin(ia); it != std::end(ia); ++it) {
printf("Char is: %d\n", *it);
}
...
and finally, range based for also supports arrays.
for (auto i: ia)
{
/* do something */
}
Can anyone explain why this has happened?
You are accessing the array out of bounds. Your program has undefined behavior.
The line
int ia[5] = {1,2,3,4,5};
creates an array with exactly 5 elements. Accessing *p after you have accessed the last element of the array is not good.
You can use:
for (int *p = ia; p != std::end(ia); ++p) {
to make sure that you don't access the array out of bounds.
You will need to add:
#include <iterator>
to use std::end.
Alternatively use sizeof() operator to determine the number of elements:
for (int *p = ia; p < ia + sizeof(ia)/sizeof(*ia); ++p) {
printf("Char is: %d\n", *p);
}
in fact the condition:
for( ; *p; )//...
will check whether the value in the address is equal to 0 or not so it stops only if the value is zero and of course this is not what you wanted; you wanted to increment the address until the last element but your code checks the value inside the address not the address itself morever the address after the lat element is not NULL.
to solve your problem you can count how many elements in the array and then inside the loop increment the pointer accordingly:
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
puts("hi");
int ia[5] = {1,2,3,4,5};
int* end = &ia[0] + 4;
for (int *p = ia; p <= end; ++p) {
printf("Char is: %d\n", *p);
}
return 0;
}

Sort command line args in C++

I wanna sort an array of command line arguments. All arguments are integer.
Here is my code, but it does not work.
#include <iostream>
using namespace std;
int main (int argc, char *argv[]) {
for (int i=0; i<argc-1; ++i) {
int pos = i;
for (int j=i+1; j<argc; ++j) {
if (argv[j] - '0' < argv[pos] - '0') {
pos = j;
}
}
char *tempt = argv[i];
argv[i] = argv[pos];
argv[pos] = tempt;
}
for (int i=0; i<argc; ++i) {
cout << argv[i] <<endl;
}
}
After compiling, when I called ./a.out 4 3 2 1, it still printed 4 3 2 1 to the screen instead of 1 2 3 4.
What's wrong?
Thanks in advance.
Try std::sort from <algorithm> with a custom comparator
std::sort(argv, argv + argc, [](char * const & a, char * const & b) {
return atoi(a) < atoi(b);
});
In modern c++ you can use auto types for lambdas. For string to int convertion I would prefer stoi function over atoi (you can look for differences here). Also worth noting that first argument (argv[0]) is a program name, e.g. ./a.out, so you need to skip it from sorting. Final result could be looks like this:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main (int argc, char *argv[]) {
std::sort(argv + 1, argv + argc, [](auto l, auto r){ return std::stoi(l) < std::stoi(r); } );
std::copy(argv + 1, argv + argc, std::ostream_iterator<const char*>(std::cout, " "));
}
If all of command line arguments a unsigned number with fixed digits count you could also sort them like string, i.e. without explicit converting to numbers via std::stoi. In this case std::vector<std::string> could be used:
std::vector<std::string> v(argv + 1, argv + argc);
std::sort(v.begin(), v.end());
There is no need to use lambda or another custom comparator for std::sort.

Default int main arguments in C/C++ [duplicate]

This question already has answers here:
What does int argc, char *argv[] mean?
(12 answers)
Closed 9 years ago.
I was messing around with projects in C/C++ and I noticed this:
C++
#include <iostream.h>
int main (int argc, const char * argv[]) {
// insert code here...
cout << "Hello, World!\n";
return 0;
}
and
C
#include <stdio.h>
int main (int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
return 0;
}
So I've always sort of wondered about this, what exactly do those default arguments do in C/C++ under int main? I know that the application will still compile without them, but what purpose do they serve?
They hold the arguments passed to the program on the command line. For example, if I have program a.out and I invoke it thusly:
$ ./a.out arg1 arg2
The contents of argv will be an array of strings containing
[0] "a.out" - The executable's file name is always the first element
[1] "arg1" - The other arguments
[2] "arg2" - that I passed
argc holds the number of elements in argv (as in C you need another variable to know how many elements there are in an array, when passed to a function).
You can try it yourself with this simple program:
C++
#include <iostream>
int main(int argc, char * argv[]){
int i;
for(i = 0; i < argc; i++){
std::cout << "Argument "<< i << " = " << argv[i] << std::endl;
}
return 0;
}
C
#include <stdio.h>
int main(int argc, char ** argv){
int i;
for(i = 0; i < argc; i++){
printf("Argument %i = %s\n", i, argv[i]);
}
return 0;
}
If you want to accept arguments through commandline ,then you need to use the arguments in the main function .argc is the argument count and array of charecter pointers list the arguments.
refer this link http://www.cprogramming.com/tutorial/c/lesson14.html
Those are for command-line arguments. argc is the number of arguments, and the arguments are stored as an array of null-terminated strings (argv). Normally, a program with no command-line arguments passed in will still have one stored in argv; namely, the name used to execute the program (which won't always be there, depending on how the program is executed, but I can't remember what the circumstances are for that).
argc and argv are how command line arguments are passed to main() in C and C++.
argc will be the number of strings pointed to by argv, this will usually be one more than the number of arguments you pass from terminal, as usually the first is the name of the program.

Calculating two numbers from command line c++

This is my code :
#include <iostream>
using namespace std;
int main (int argc, char* argv[])
{
int frstNumb = atoi (argv[1]);
int scndNumb = atoi (argv[2]);
int sum = 0;
sum = frstNumb + scndNumb;
}
Okay, now its working for integers. What do I must do so I can put e.g. "2.5 and 1.2" in my parameters? This program won't calculate that kind of numbers. Help?
Thanks
The arguments are always passed as strings. First of all, change the main function declaration to
int main (int argc, char* argv[])
Note that the return value of main MUST be int, otherwise it is nonstandard.
Second convert argv[1] and argv[2] to integers with either atoi , which, to my taste, is a bit C-ish, although the simplest, or by boost::lexical_cast
e.g.
int i1 = atoi(argv[1]); //#include <cstdlib>
int i1 = boost::lexical_cast<int>(argv[1]); //#include <boost/lexical_cast.hpp>
Yep-- you want atoi().
int frstNumb = atoi(argv[1]);
int scndNumb = atoi(argv[2]);
I'd suggest googling atoi() to see how it works, it will probably help you in the future.
argv[1] and argv[2] are strings. When you do the sum, wrap them with atoi() calls so they are parsed and converted to integers.
Thanks to Mark Loeser and walkingTarget
Your declaration of main() should be:
int main(int argc, char **argv)
or
int main(int argc, char *argv[])
main() should always return an int, and argv should always be an array of strings.
As suggested in other answers, you first need to change declaration of function main - argc represents total number of arguments passed to it and argv is an array of arguments themselves (each argument is an element in array; first element - argv[0] - is path to this executing binary! argv[1] is actually first argument from a command line).
Both in C and C++ you can use atoi or sscanf functions but in C++ you should take advantage of STL stringstream's conversion capabilities:
#include <iostream>
#include <sstream>
using namespace std;
int main(int argc, char* argv[])
{
if(argc != 3)
{
cerr << "Invalid number of operands" << endl;
return 1;
}
int n1 = 0;
int n2 = 0;
stringstream ss;
ss << argv[1];
ss >> n1;
ss.clear();
ss << argv[2];
ss >> n2;
int sum = n1 + n2;
return 0;
}

while infinite loop?

I came across this question in this forum
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int x=0;
while (x<3) {
x = x++;
cout << x << endl;
}
return 0;
}
given the code above, why is the while loop infinite? Using gcc 4.4 under mac os, the while loop does terminate :) so the question does not apply for all architectures. The output I get tough is
1
2
3
I don't see 0, and I guess the reason is related to the double assignment?
x = x++;
is undefined behavior
you never see zero because the increment is before the cout.