Using Ranges from command line - c++

I have a task which is ,I need to display to the user the mathematical tables the user wants . However the input must be using command line arguments . I know how to do this with single input .. however I have to add a functionality so that when the user types : my program 5-7 i have to display the multiplicative tables of 5 ,6 and 7 ..how can I work around with this ?
This must be done in C++
This is my code :
#include <iostream>
#include <cctype>
#include <iomanip>
using namespace std;
int main(int argc,char *argv[]){
int i;
locale loc;
int tables[argc-1];
if(argc <=1){
cout<<"NO ARGUMENTS PASSED"<<endl;
exit(0);
}
for(i=1;i<=argc;i++){
if( isdigit(argv[i],loc)){
tables[i] = atoi(argv[i]);
}
}
for (i=1; i<=argc;i++){
cout<<argv[i]<<endl;
}
}

First decide whether to handle "tables 2-3", "tables 2 - 3" or both.
Lets say we opt for both. So argc must be either 2 for the one argument case (remember argv[0] is the program name) or 4 for the three argument case. if it's not 2 or 4, print out a usage message to tell the user how to use the program and quit.
If is is 4, argv[1] must be an integer, argv[2] must be the string "-", and argv[3] must be an integer. You might also require that argv[3] be greater than argv[1].
So test these. strcmp will test for the middle. The function strtol() provides an easy way to test for a valid integer (the end pointer should point to the nul on exit if it is an integer).
If argc is 2, the string must be in the forma 12-30, an integer,a hyphen and an integer. There are several ways of testing for this. One is to call strtol, then check that the end pointer points to hyphen, then call strtol again on the character after the hyphen. You could also use the function sscanf().
Now decide how to handle cases such as negative or zero, and huge values maybe beyond your machine precision.
Finally print out the tables.

Related

How to get correct number from args?

I write an application, which get a number from args.
ex:./app --addr 0x123 or ./app --addr 123
I don't know which api can identify if the parameter is hex or decimal and come up with the correct data?
Thanks.
One way of getting the arguments is through argc and argv in
int main(int argc, char* argv[]) {
// Some code here.
return;
}
This will give you an array with all the arguments as strings. For example:
#include <iostream>
int main(int argc, char* argv[]) {
for (int i{ 0 }; i < argc; i++)
std::cout << "Argument " << i << ": " << argv[i] << std::endl;
return;
}
will give you this output
$ ./app --addr 0x123
Argument 0: ./app
Argument 1: --addr
Argument 2: 0x123
Now, parsing the input is a bit more complicated. You could create your own logic to evaluate the arguments once you have the arguments as strings.
You could also use libraries. For example, you could use argparse by p-ranav. GitHub repository here. It is an easy to use library so you don't have to worry about positioning of the arguments.
Answering you question, how do you know if the input is hex or decimal? You could check if the argument after --addr starts with 0x or not. That could be one way, but you have to also consider the case when someone inputs a hex value without the 0x, like ./app --addr A2C. Also, documenting acceptable formats and printing a --help message can ameliorate this.
You have to think about your specific application, but some steps once you have the string after --addr that you could do to check input is:
Does it start with 0x?
If not, does it contains characters 0-1 and A-F? Is this allowed?
Is it in a valid range?
For example, 0xFFFFF is 1,048,575. But you may only want addresses up to 0xFFFF (65,535). What should happen in these cases?
Hope it helps!
P.S.: These are all implementations in C++.
strtol will do the job for you
https://www.cplusplus.com/reference/cstdlib/strtol/

make user enter a string of integers and output a different string

hi i am having trouble starting this program as i am new and have no idea how to use loops to construct this thanks
here are the directions:
For this assignment, write a program named assignment2 (source is the same name with .cpp extension) to
prompt the user for an integer value (ignore negative values) and then output this value using the following rules:
Each digit within the integer value is to be displayed the same number of times as the value of the digit
itself, with one exception...the digit 0 will be displayed once, like the digit 1.
Separate each string of digits using a single dash character.
For example:
If the input value is 120473, the display should look like:
1-22-0-4444-7777777-333
If the input value is 5938061, the display should look like:
55555-999999999-333-88888888-0-666666-1
In addition, ask the user if they would like to retry using another integer value. If so, repeat the above. End the
program when the user chooses to quit (does not want to retry).
This assignment is an exercise in using the following:
Unary Operators:
! ++ --
Binary Operators:
+ - * / % && ||
Data types:
bool
char
int
enum
Flow control:
if-else
switch
do-while loop
while loop
for loop
In addition, you are allowed to use any necessary functions provided by the Math library. To include the Math
library, add the following line to your list of include statements:
#include <cmath>
For most digit manipulation assignments, I recommend treating the number as a string of characters rather than as a number.
The Foundation
Let's start with the foundation:
#include <iostream>
#include <string>
#include <cstdlib>
using std::cout;
using std::cin;
using std::getline;
int main(void)
{
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
return EXIT_SUCCESS;
}
The above program will hopefully keep the console (terminal) window open until the Enter key is pressed.
Getting The Input
We'll ask the User for a number, this is also known as prompting:
// The prompt text doesn't change so it's declared as const.
// It's declared as static because there is only one instance.
static const char prompt[] = "Enter a number: ";
cout.write(prompt, sizeof(prompt) - 1U); // Subtract 1 so the terminating nul is not output.
// Input the number as text
string number_as_text;
getline(cin, number_as_text);
Printing The Digits
Really, before this step, you should verify that the text only contains numbers. Repeat the prompting until the User inputs nothing or valid data.
A string can be accessed as an array. So we'll set up a loop:
const unsigned int length = number_as_text.length();
for (unsigned int index = 0U;
index < length;
++index)
{
// Extract the digit.
const char c = number_as_text[index];
// Verify it is a digit.
if (!isdigit(c))
{
continue;
}
unsigned int quantity = c - '0'; // Convert to a number.
if (quantity == 0) quantity = 1; // The requirements lie, for zero there is a quantity of 1.
// Use "quantity" to print copies of the character.
}
cout << "\n";
Stuff
I'm not going to write the entire program for you, as you haven't paid for my services. So you will have to figure out when to print the '-' and how to print many copies of the digit.
If this answer is not correct, please update your question with some clarifications or restrictions.

Execute .exe file from c++ code + enter values

I'm relatively new to c++, and I'm just making some simple programs.
One of my programs will need to open up a different .exe file. This .exe file will ask for 2 or 3 file names, then run and exit.
Just to test this out, I created a simple_calc.exe file, that ask for value1, then value2 then multiply them.
So let's say I want to create a "call_other_file.exe" and automatically run "simple_calc.exe" with value1 and value2 taken from "call_other_file.exe"s file.
How can I proceed to do that?
After searching a bit, i see something like:
system("simple_calc.exe -val1 -val2").
But that doesn't work for me. Or I'm not sure how to define val1 and val2...
edit: the program I want to access (simple_calc.exe in the example), I can not change the code there, I don't have access to it's .cpp file.
Any suggestions?
i see something like: system("simple_calc.exe -val1 -val2")
It should work. The reason why that didn't work might be that you didn't put int argc, char* argv[] in your "simple_calc"'s main function.
//simple_calc.cpp
int main(int argc, char* argv[])
{
if (argc == 2)
{
cout << "Error: At least two argument must be exist.";
return -1;
}
return 0;
// After that, you can use 'argv' arguments to calculate what you want to calculate. Also, in order to calculate them, you also need to convert 'argv' to integer or double, since they are string or char array.
}
For more information on C++ comand-line arguments see this site below:
http://www.tutorialspoint.com/cprogramming/c_command_line_arguments.htm
When you add the command-line arguments to your simple_calc.cpp, you can use this simple_calc.exe val1 val2. To call another program from your C++ program, you need system calls. In your main function;
system('simple_calc.exe')
You also need to know about how windows console work, if you are using windows. If you are using linux, its console commands are also different.
My suggestion is that you must first learn how consoles work different operating systems.
There are various ways to have two separate programs communicate with one another, but the system() function is probably the simplest; it just runs a string of text as though it were entered in a console window.
Basic example
The main program simply runs the other program with two arguments: hello and world.
/* main.c */
#include <stdlib.h>
int main() { return system("./other hello world"); }
The two arguments will be passed to the other program as C-style strings via the argv[] array. Note that they will be stored as the second and third elements, since the first item (argv[0]) will be the path to the program itself.
/* other.c */
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 0;
for (i = 1; i < argc; ++i) { printf("%s\n", argv[i]); }
return 0;
}
The output of the above programs will look like this:
hello
world
Process returned 0 (0x0) execution time : 0.004 s
Press ENTER to continue.
Arguments with spaces
As you may have noticed, arguments are space-separated. If you need to pass a string with spaces as a single parameter, you'll need to enclose it in quotes:
/* main.c */
#include <stdlib.h>
int main() { return system("./other \"this is all one string\" \"and so is this\" bye"); }
This would produce the following result:
this is all one string
and so is this
bye
Process returned 0 (0x0) execution time : 0.004 s
Press ENTER to continue.
Non-string arguments
Since the arguments are given as strings, you'll need to convert them into numbers (using conversion functions such as strtod(), atoi(), or atof()) if necessary. Here's an updated version of main.c:
/* main.c */
#include <stdlib.h>
int main() { return system("./other 4 6"); }
...and here's the corresponding other.c file:
/* other.c */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int total, i;
for (total = 0, i = 1; i < argc; ++i) { total += atoi(argv[i]); }
printf("TOTAL: %d\n", total);
return 0;
}
This produces the following output:
TOTAL: 10
Process returned 0 (0x0) execution time : 0.005 s
Press ENTER to continue.

What is wrong with my UVa code

I tried to solve this problem in UVa but I am getting a wrong answer and I cant seem to find the error
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2525
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,j,k,i=1;
char a[1000];
while(scanf("%d",&t)!=EOF && t)
{
int sum=0;
getchar();
gets(a);
k=strlen(a);
for(j=0;j<k;j++)
{ if(a[j]=='a'||a[j]=='d'||a[j]=='g'||a[j]=='j'||a[j]=='m'||a[j]=='p'||a[j]=='t'||a[j]=='w'||a[j]==32)
sum=sum+1;
else if(a[j]=='b'||a[j]=='e'||a[j]=='h'||a[j]=='k'||a[j]=='n'||a[j]=='q'||a[j]=='u'||a[j]=='x')
sum=sum+2;
else if(a[j]=='c'||a[j]=='f'||a[j]=='i'||a[j]=='l'||a[j]=='o'||a[j]=='r'||a[j]=='v'||a[j]=='y')
sum=sum+3;
else if(a[j]=='s'||a[j]=='z')
sum=sum+4;
}
printf("Case #%d: %d\n",i,sum);
i++;
}
return 0;
}
In the problem description there is a single number that indicates the number of texts that will be in the input afterwards. Your original code was trying to read the number before every row of input.
The attempt to read the number in each one of the rows will fail since the input character set does not include any digits, so you could be inclined to think that there should be no difference. But there is, when you try to read a number it will start by consuming the leading whitespace. If the input is:
< space >< space >a
The output should be 3 (two '0' and one '2' keys), but the attempt to read the number out of the line will consume the two leading whitespace characters and the later gets will read the string "a", rather than " a". Your count will be off by the amount of leading whitespace.
separate your code into functions that do specific things: read the data from the file, calculate the number of key presses for each input, output the result
Benefit:
You can test each function independently. It is also easier to reason about the code.
The maximum size of an input is 100, this means you only need an array of 101 characters( including the final \0) for each input, not 1000.
Since this question is also tagged C++ try to use std::vector and std::string in your code.
The inner for seems right at a cursory glance. The befit of having a specialized function that computes the number of key presses is that you can easily verify it does the correct thing. Make sure you check it thoroughly.

Matching russian vowels in C++

I wanted to write a function which returns true if a given character is a russian vowel. But the results I get are strange to me. This is what I've got so far:
#include <iostream>
using namespace std;
bool is_vowel_p(char working_char)
// returns true if the character is a russian vowel
{
string matcher = "аяё×эеуюыи";
if (find(matcher.begin(), matcher.end(), working_char) != matcher.end())
return true;
else
return false;
}
void main()
{
cout << is_vowel_p('е') << endl; // russian vowel
cout << is_vowel_p('Ж') << endl; // russian consonant
cout << is_vowel_p('D') << endl; // latin letter
}
The result is:
1
1
0
what is strange to me. I expected the following result:
1
0
0
It's seems that there is some kind of internal mechanism which I don't know yet. I'm at first interested in how to fix this function to work properly. And second, what is going on there, that I get this result.
string and char are only guaranteed to represent characters in the basic character set - which does not include the Cyrillic alphabet.
Using wstring and wchar_t, and adding L before the string and character literals to indicate that they use wide characters, should allow you to work with those letters.
Also, for portability you need to include <algorithm> for find, and give main a return type of int.
C++ source code is ASCII. You are entering unicode characters. The comparison is being done using 8 bit values. I bet one of the vowels fulfills the following:-
vowel & 255 == (code point for 'Ж') & 255
You need to use unicode functions to do this, not ASCII functions, i.e. use functions that require wchar_t values. Also, make sure your compiler can parse the non-ASCII vowel string. Using MS VC, the compiler requires:-
L"аяё×эеуюыи" or TEXT("аяё×эеуюыи")
the latter is a macro that adds the L when compiling with unicode support.
Convert the code to use wchar_t and it should work.
Very useful function in locale.h
setlocale(LC_ALL, "Russian");
Past this in the beginning of the program.
Example:
#include <stdio.h>
#include <locale.h>
void main()
{
setlocale(LC_ALL, "Russian");
printf("Здравствуй, мир!\n");//Hello, world!
}
Make sure your system default locale is Russian, and make sure your file is saved as codepage 1251 (Cyrillic/Windows). If it's saved as Unicode, this won't ever work.
The system default locale is the one used by non-Unicode-compliant programs. It's in Control Panel, under Regional settings.
Alternatively, rewritte to use wstring and wchar_t and L"" string/char literals.