Trouble with argc and argv - c++

Trying to add command line arguments to my programs. So I was experimenting and cannot figure out this intellisense warning for the life of me. It keeps on saying it is expecting a ')', but I have no idea why.
Here is the code it does not like:
// Calculate average
average = sum / ( argc – 1 );
Then it underlines the subtraction operator. Below is the full program.
#include <iostream>
int main( int argc, char *argv[] )
{
float average;
int sum = 0;
// Valid number of arguments?
if ( argc > 1 )
{
// Loop through arguments ignoring the first which is
// the name and path of this program
for ( int i = 1; i < argc; i++ )
{
// Convert cString to int
sum += atoi( argv[i] );
}
// Calculate average
average = sum / ( argc – 1 );
std::cout << "\nSum: " << sum << '\n'
<< "Average: " << average << std::endl;
}
else
{
// If invalid number of arguments, display error message
// and usage syntax
std::cout << "Error: No arguments\n"
<< "Syntax: command_line [space delimted numbers]"
<< std::endl;
}
return 0;
}

The character you think is a minus sign is something else, so it is not parsed as a subtraction operator.
Your version:
average = sum / ( argc – 1 );
Correct version (cut and paste into your code):
average = sum / ( argc - 1 );
Note that calculating an average using integers might not be the best way to do it. You have integer arithmetic on the RHS, which you then assign to float on the LHS. You should perform the division using floating point types. Example:
#include <iostream>
int main()
{
std::cout << float((3)/5) << "\n"; // int division to FP: prints 0!
std::cout << float(3)/5 << "\n"; // FP division: prints 0.6
}

I tried to compile your code on my machine with g++ 4.6.3 and got the follow error:
pedro#RovesTwo:~$ g++ teste.cpp -o teste
teste.cpp:20:8: erro: stray ‘\342’ in program
teste.cpp:20:8: erro: stray ‘\200’ in program
teste.cpp:20:8: erro: stray ‘\223’ in program
teste.cpp: Na função ‘int main(int, char**)’:
teste.cpp:16:33: erro: ‘atoi’ was not declared in this scope
teste.cpp:20:35: erro: expected ‘)’ before numeric constant
Looks like there is some strange char in that line. Remove and re-write the line fixed the error.

Related

Check that command line input is one argument and it must be a numeric greater than 3 only in c++

Program in c++.
My goal for this assignment is to make sure the user enter only one argument in command line and that argument has to contain digits only and greater than 3. Otherwise, print error.
For example:
$ ./a.out 4
Successful!
$ ./a.out abc
Must be a numeric string grater than 3
$ ./a.out 4 abc
Must be one argument only
$ ./a.out 2
Must be a numeric string greater than 3
$ ./a.out 2ab
Must be a numeric string
This is my code so far to handle accepting one argument and greater than 3. I don't know to handle the numeric string part.
int main(int argc, char **argv){
if (argc == 2){
int num = atoi(argv[1];
if (num >3){
cout << "Successful" << endl;
else{
cout <<"Must be a numeric string greater than 3"<< endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
I have tried this and got segmentation error.
int main(int argv, char **argv){
if (argc == 2){
int num = atoi(argv[1];
int i;
if (num >=3 && isdigit(argv[1][i]){
cout << "Successful" << endl;
else{
cout << "Must be a numeric string greater than 3"<<endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
You could use std::strtol instead of atoi; this way you can check that the parsing stopped at the end of that string.
here is code that compiles and does not crash but doesn't produce the right answer. It doesn't work because you are only looking at the first char of argv[1]. Why did it crash, becuase you indexed using i which was untitialized
#include <iostream>
#include<ctype.h>
int main(int argc, char** argv) {
if (argc == 2) {
int num = atoi(argv[1]);
int i = 0;// <<<<========================================
if (num >= 3 && isdigit(argv[1][i])) {
std::cout << "Successful" << std::endl;
}
else {
std::cout << "Invalid" << std::endl;
}
}
else {
std::cout << "Must be one argument" << std::endl;
}
return 0;
}
to make it do the right thing you need to loop over all argv and inside that loop you must loop over all chars in argv[i]
note that I removed the using namespace - see here Why is "using namespace std;" considered bad practice?
Your text and your code are at odds with each other. Is 3 acceptable or not? My code below assumes it is not based on what you wrote.
The big thing here is that atoi() lacks the ability to tell you if the whole string was processed or not. You want to use what C++ provides from <string>, std::stoi() or the long or long long variations depending on what you expect a reasonable range of inputs to be.
std::stoi() has a second output parameter that tells you how many characters were processed. What you then need to check is if the number of characters processed is the length of the string. If not, some non-numeric charcters were entered.
Example code below.
#include <cstring>
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "USAGE: ./a.out ARG\n";
return 1;
}
std::size_t loc;
int val;
// The try block is necessary because std::stoi() throws if the resulting
// number cannot be contained in the type, and if processing fails on the
// first character.
try {
val = std::stoi(argv[1], &loc);
} catch (...) {
std::cerr << "INVALID PARAMETER\n";
return 2;
}
if (loc != std::strlen(argv[1])) {
std::cerr << "INPUT MUST BE FULLY NUMERIC\n";
return 3;
}
if (val <= 3) {
std::cerr << "Parameter must be > 3\n";
return 4;
}
std::cout << "Parameter: " << val << '\n';
}
Test runs:
~/tmp
❯ ./a.out
USAGE: ./a.out ARG
~/tmp
❯ ./a.out 1
Parameter must be > 3
~/tmp
❯ ./a.out 4
Parameter: 4
~/tmp
❯ ./a.out 2ab
INPUT MUST BE FULLY NUMERIC
~/tmp
❯ ./a.out ab
INVALID PARAMETER
Other answers are good and correct. My goto for stuff like this is to use a stringstream.
#include <optional>
#include <sstream>
#include <string>
template <typename T>
auto string_to( const std::string & s )
{
T value;
return (std::istringstream( s ) >> value >> std::ws).eof()
? value
: std::optional <T> {};
}
It is easy enough to use:
#include <iostream>
int error( const char * message )
{
std::cerr << message << "\n";
return 1;
}
int main( int argc, char ** argv )
{
if (argc != 2) return error( "Must be one argument only" );
auto n = string_to<int>( argv[1] );
if (!n) return error( "Must be a numeric string" );
if (n <= 3) then error( "Must be a numeric string grater than 3" );
std::cout << "Successful!\n";
}
The basic principle behind all these answers is you must try to convert it to an integer to see if it is, in fact, an integer.
I like my little utility function (string_to<type>()) because it does all the dirty work correctly: it attempts to convert the value, meaning there may be whitespace before the value but nothing else. It then reads any remaining whitespace and checks for EOF (meaning nothing but whitespace may follow the value). Only if all the checks pass do you get a value back.
I like std::optional because it is exactly for these kinds of things — either you have a value or you do not. You could throw instead, or return a default value, or whatever works. Heck, you could inline it in your main function:
int main(...)
{
...
int value;
if (!(std::istringstream( argv[1] ) >> value >> std::ws).eof())
error( ... );
That’s ugly though, and not very descriptive. I prefer to put things in little helper functions (which the compiler may very well inline) with nice, descriptive names. Like that error function I used there: it tells you exactly what is going on just by reading the code.

Seeking advice on runtime error related to uncaught exception of type std::invalid_argument: stoi: no conversion

I am writing a test C++ program to find out the difference bits between two numbers.
Header file - code.hpp:
#ifndef CODE_HPP
#define CODE_HPP
#include<iostream>
#include<string>
#include<algorithm>
using std::cout;
using std::string;
using std::reverse;
using std::stoi;
using std::endl;
class calcDiffBits{
public:
calcDiffBits(int,int);
~calcDiffBits();
private:
void calc();
string conv2Bin(int);
int i;
int j;
};
calcDiffBits::calcDiffBits(int n, int m):i(n),j(m){
calc();
}
calcDiffBits::~calcDiffBits(){}
void calcDiffBits::calc(){
string s1 = conv2Bin(i);
string s2 = conv2Bin(j);
#ifdef DBG
cout << "Binary Value of i:" << s1 << endl;
cout << "Binary Value of j:" << s2 << endl;
#endif
auto iBin = stoi(s1, nullptr, 2);
auto jBin = stoi(s2, nullptr, 2);
auto xorRes = iBin ^ jBin;
auto diffCount = 0;
do{
xorRes >>= 1;
++diffCount;
}while(xorRes);
cout << i << " and " << j << " differ by " << diffCount << " bits.";
cout << endl;
}
string calcDiffBits::conv2Bin(int n){
auto rem = 0;
string s = "";
do{
rem = n % 2;
s += rem;
}while(n /= 2);
reverse(s.begin(), s.end());
return s;
}
#endif
Source file - main.cpp:
#include "code.hpp"
using std::cin;
int main(){
int i, j;
cout << "Enter the digits:";
cin >> i >> j;
calcDiffBits obj(i,j);
return 0;
}
After successfully compiling the code using the following command:
g++ -DDBG -ggdb -std=c++14 -Wall main.cpp -o calcDiffBits
I found upon running the program that I was getting the following runtime error:
libc++abi.dylib: terminating with uncaught exception of type
std::invalid_argument: stoi: no conversion Abort trap: 6
Upon debugging using the debug prints in the code, I could see that the string returned by the function conv2Bin() is a null string, because of which the runtime error occurs.
I further debugged the function conv2Bin() using GDB and could find that the algorithm adopted inside the function was working as expected. In other words, each time the value in the variable rem was getting appended to the string s.
So why does the value returned from the function conv2Bin() turn out to be a null string?
I think the problem is that you add an int to a string, which you later attempt to parse as if it was a valid ASCII representation of a number.
The line in question is
s += rem;
where rem is either 0 or 1, not '0' or '1'

Run-time error, using undeclared variable, C++

Im having this really weird error during run-time.
My program takes two parameters, does some math calculus with them and std::cout's the values in the end.
My program works if i input somevalues, but if i input other values it says that a variable is being used without being initialized, which i think it makes no sence.
Here is the code:
#include <iostream>
#include <stdio.h>
#include <cmath>
double align_nb(int n) { return { ceil(n / 512.0)*512.0 }; } // bytes
double align_pt(int k) { return { floor(k / 512.0)*512.0 }; } // pointer
int main(int argc, char * argv[])
{
int o_n = std::atoi(argv[1]); // original number
int o_p = std::atoi(argv[2]); // original pointer
int max_bytes, new_pointer; // max bytes to read, new pointer to point
float log = (std::log(o_n) / std::log(2));
if (log != floor(log))
{
max_bytes = align_nb(o_n); // bytes alinhados para a frente
new_pointer = align_pt(o_p); // ponteiro alinhado atrás
}
else if (log == floor(log))
{
new_pointer = align_pt(o_p);
if (max_bytes + (o_p - new_pointer) >max_bytes)
{
max_bytes += 512;
}
}
std::cout << "Original bytes= " << o_n << std::endl;
std::cout << "Original pointer= " << o_p << std::endl;
std::cout << "Max_bytes= " << max_bytes << std::endl;
std::cout << "new_pointer= " << new_pointer << std::endl;
return 0;
}
Here are the values i tested it and it crashed, giving me that run-time error:
2048 513
1024 500
here is one example of values were the code doesnt give me that error and the program works:
513 520
Here is a print of the error it gives me.
I'd really appreciate someone explaining me why it gives me that error/how to fix it.
Regardless, thanks!
(PS: math tag is included cause it could be the math in the program that is causing it to crash. If annyone thinks it shoudlnt be used in this question, let me know in the comments and ill remove it.)
(PS 2: the variable it complains when it gives me the run time error is 'max_bytes'.)
If your code takes the else path at line 17, then your code doesn't initialize max_bytes, but uses it afterwards. That's the problem.
Notes:
comparing calculated floating point values for equality usually a bad practice
you don't need the additional if at line 23.
Make sure that for each path your code takes the values of the variables you use are initialized. If you don't you get what is called Undefined Behaviour. There could be anything in an uninitialized variable.
int max_bytes;
....
....
expression_involving_max_byte <- Dangerous!

Compiling two programs fails

For an assignment I have written two programs.
One for generating a file of random integers, the other for counting integers less than a specified threshold.
You can find the actual assignment texts below the code I've posted.
When compiling g++ generate.cpp -o generate, I get this error:
z1755294#hopper:~/assign2$ g++ generate.cpp -o generate
generate.cpp: In function ‘bool writeRand(int, int, int, const char*)’:
generate.cpp:12:31: error: variable ‘std::ofstream fout’ has initializer but incomplete type
ofstream fout ( fname );
When I compile g++ thresh.cpp -o thresh, I get this error:
z1755294#hopper:~/assign2$ g++ thresh.cpp -o thresh
thresh.cpp: In function ‘int main()’:
thresh.cpp:19:16: error: variable ‘std::ifstream fin’ has initializer but incomplete type
ifstream fin( fname.c_str() );
Can anyone help me fix my code to get it working? Also I need to create a Makefile for my project since I have multiple executables?
Thanks so much...kinda stuck on what to do.
This is my code:
generate.cpp
#include <iostream>
#include <cstdlib> // re. atoi
using std::cout;
using std::endl;
using std::cerr;
using std::ifstream;
using std::ofstream;
bool writeRand ( const int ranSeed, const int maxVal, const int numVals, const char* fname )
{
ofstream fout ( fname );
if ( fout )
{
srand ( ranSeed );
for ( int i=0; i < numVals; ++ i )
fout << rand () % (maxVal+1) << endl;
fout.close ();
return true;
}
//else
return false;
}
int main ( int argc, char* argv [] )
{
if (argc !=5 )
{
cerr << "Usage: " << argv[0] << "ranSeed maxVal numVals outFileName" << endl;
return -1;
}
const int ranSeed = atoi(argv[1]);
const int maxVal = atoi(argv[2]);
const int numVals = atoi(argv[3]);
const char* fname = argv[4];
if ( ranSeed <= 0 || maxVal <= 0 || numVals <= 0 )
{
cerr << "Invalid negative or zero numbers on command line....Try again..." << endl;
return -1;
}
if ( writeRand( ranSeed, maxVal, numVals, fname ) )
cout << "ranSeed = " << ranSeed << ", maxVal = " << maxVal << ", numVals = " << numVals
<< "\nfame " << fname << " was created ok ..." << endl;
else
cout << "There was a problem creating file " << fname << " ..." << endl;
}
thresh.cpp
#include <iostream>
#include <cstdlib> // re. atoi
using std::cout;
using std::endl;
using std::cin;
using std::ifstream;
using std::string;
using std::flush;
int main ()
{
//prompt and take in the desired file name
cout << "Enter name of file (for example randNums.txt): " << flush;
string fname;
getline( cin, fname );
//then can open file
ifstream fin( fname.c_str() );
if( fin )
{
int max, count = 0, below = 0, val = 0;
string line;
while( true )
{
cout << "Enter the threshold value: " << flush;
getline( cin,line );
max = atoi( line.c_str() );
if( max > 0 ) break;
cout << "Try again with value > 0 \n";
}
while( getline( fin, line) )
{
val = atoi( line.c_str() );
++count;
if( val < max ) ++below;
}
fin.close();
cout << below << " of " << count << " values in file '"
<< fname << "' are less than " << max << '\n';
max = val+1; //last value (in file) + 1
count = 0, below = 0;
fin.open( fname.c_str() );
while( getline( fin, line ) )
{
int val = atoi( line.c_str() );
++count;
if( val < max ) ++below;
}
fin.close();
cout << below << " of " << count << " values in file '"
<< fname << "' are less than " << max << '\n';
}
else
cout << "There was an error opening file " << fname << '\n';
cout << "Please 'Enter' to continue/exit..." << flush;
cin.get();
return 0;
}
Assignments
generate
Create a program called "generate" which generates a file of random integers.
This program takes four command line arguments. They are, in order
*A random number seed. This is an integer value explained below.
*A maximum value. The random values should be less than this maximum. This value is an integer.
*The number of values to be generated
*The name of an output file to store the values
If the command line arguments are not given, the program should give a brief message on proper usage and then exit. The integer values on the comand line should all be checked for negative values. If a negative value is given, the program should print an error message and exit.
Random number generation
The rand() function, found in returns a random positive integer every time it is called. The srand(int) function takes an integer called the random number seed which is used to initialize the random number generator. Subsequent calls to rand() produce a random sequence which is uniquely tied to its seed. Typically in a program, srand() is called once, while rand() is called multiple times.
A common technique for producing random numbers of a particular size is to use the remainder of divding rand() by the maximum upper bound.
thresh
Create a program called thresh which should ask the user for a file name and an integer threshold value. The program should then count the number of values in the file less than the threshold and report the results.
For example, 43 of 300 values in mydatafile are less than 17
This program should not use command line arguments. Rather, needed values should be obtained by prompting the user.
When asking for the threshold value, if the user inputs a negative value, the program should print an error and loop on the request until a proper value is obtained.
If the input file does not exist, an error message should be printed and the program should exit.
Hints:
Test your programs with small values that can be checked by hand. For example, create a file of 20 values less than 10. A particularly good test of thresh is to use the last value of the data file as a threshold value. Then use the last value plus one as a threshold value.
**A Makefile is required as part of your submission. If the project has multiple executables, you should have a default makefile rule to build all of the executables. You should have a rule to clear out the project to a pristine state. Your Makefile should use appropriate variables.
As #mrunion pointed out, you should replace
g++ generate.cpp thresh.cpp
with g++ generate.cpp
and g++ thresh.cpp
By the way, if you do these back to back, you'll overwrite your executable. An improvement would be:
g++ generate.cpp -o generate
and
g++ thresh.cpp -o thresh

Errors in a sqrt function program in c++

**Essentially I was given pseudo code:
"x = 1
repeat 10 times: x = (x + n / x) / 2
return x"
And the pseudo code for the int main function (int main function to print out my n values in the cout) at the end, in order to create a sqrt function program. I get the following errors on linux2 compiler:
: In function ‘double my_sqrt_1(double)’:
:9:1: error: expected primary-expression before ‘return’
:9:1: error: expected ‘;’ before ‘return’
: In function ‘int main()’:
:
15:13: error: expected unqualified-id before ‘-’ token
:~> expected primary-expression before ‘return’
Help is much appreciated!
#include <iostream>
#include <math.h>
using namespace std;
double my_sqrt_1(double n)
{
for (int x= 1; x<10; ++x)
cout<< x << '\t' << x=(x+n/x)/2 <<
return x;
}
int main()
{
int n= 3.141459;
int k= -100,-10,-1,0,1,10,and 100;
for(auto k : { -100,-10,-1,0,1,10,100}){
n=3.14159 * pow (10.0,k);
cout << "print n,sqrt(n),and my_sqrt_1(n)" ;
return 0;
}
}
You missed a semicolon at the end of the cout line:
double my_sqrt_1(double n)
{
for (int x= 1; x<10; ++x)
cout<< x << '\t' << x=(x+n/x)/2;
return x;
}
The clue is in the error:
:9:1: error: expected ‘;’ before ‘return’
Finding the source of compiler errors can be tricky for those new to C/C++, if you miss a semi-colon the line reported will often differ from the one containing the actual error. As in this case where the return line became part of the same statement as the line above.
Also here:
int k= -100,-10,-1,0,1,10,and 100;
That is not how you define an array, you should read up on the basics of those since you're new to the game, which is evident here:
cout << "print n,sqrt(n),and my_sqrt_1(n)" ;
Where you're not calling any functions but instead outputting a static string of text. You need to make the function calls and variable outputs outside of the literal string:
cout << "print " << n << "," << sqrt(n) << ", and" << my_sqrt_1(n);