Alrighty, so my instructor doesn't seem to want to move on from this code. So I've had to modify it a few times since I last came on here for help and I'm stumped on something new. We are supposed to have our code take command line arguments now. I've been reading everything I can on command line arguments and I just don't get it. I put "int arc, char *argv[]" in the parameters of main but I have no clue what to do now. My TA's told me how easy it was and that I just have to "access the conversion functions with argv[]." That blew my mind and I don't know and I still don't know where to begin. I'm supposed to be able to execute the file with ./filename -b "binary number" -a "characters".
How might I go about doing such a thing. As always any hints and useful bits of information are greatly appreciated.
#include <iostream>
#include <string>
#include <bitset>
#include <sstream>
#include <algorithm>
usingnamespace std;
void get_user_char( string &char_in ) // Char_in value passes to bin_out.
{
cout << endl;
// Prompt user for a string of characters.
cout << "Enter a string of characters: ";
// Reads the user's input and gives that value to char_in.
getline( cin, char_in );
cout << endl;
}
void get_user_bin( string &bin_in ) // Bin_in value passes to char_out.
{
// Prompt user for binary string.
cout << endl << "Enter a string of binary: " << endl;
bool correct_input = false;
/* While loop prompts the user to enter a binary
* string until only 1's and 0's are entered.*/
while ( !correct_input )
{
// Read the users input and gives it to bin_in.
getline( cin, bin_in );
// all_of checks that all elements in the range are true.
correct_input = all_of( bin_in.begin(), bin_in.end(), [](char bit){ return bit == '1' || bit == '0'; } );
// Error promt.
if ( !correct_input )
{
cout << "Error, print only 1's and 0's: ";
}
}
// Return the users binary input.
cout << endl << "You entered: " << endl << bin_in << endl;
}
string char_to_bin( string bin_out ) // Convert ASCII to binary.
{
// Return the users ASCII input.
cout << "You entered: " << bin_out << endl << endl;
// A-B Conversion.
cout << "Your input in binary is: " << endl;
// size_t is an unsigned integral type that works with the sizeof operator.
for ( size_t i = 0; i < bin_out.size(); ++i )
{
// Prints binary values of the characters.
cout << bitset<8>( bin_out[i] );
// Bitset stores the characters into their bytes.
}
cout << endl;
return bin_out;
}
string bin_to_char( string char_out ) // Convert binary to ASCII.
{
// Allows the sequence of strings to be accessed directly as a string.
istringstream in( char_out );
// Divides the bits into bytes.
bitset<8> bs;
cout << endl << "Your input in ASCII is: ";
// B-A Conversion
// Loop extracts the bytes in the string and prints them as there ascii values.
while ( in >> bs )
{
cout << char( bs.to_ulong() );
}
cout << endl;
return char_out;
}
void ohm_border() // Seperates code output from other things on the flip screen.
{
cout << endl << "=======================================================" << endl;
}
void tilda_border() // Separates char→bin and bin→char sections of the code's outputs.
{
cout << endl << "-------------------------------------------------------" << endl;
}
int main( int argc, char *argv[] )
{
string input1, input2;
ohm_border();
get_user_char( input1 );
char_to_bin( input1 );
tilda_border();
get_user_bin( input2 );
bin_to_char( input2 );
ohm_border();
return 0;
}
Sadly I'm still confused. I actually came across that example and I couldn't figure out how to apply it to my code. So, can I just put my function calls in an if statement or a for statement like:
if (argc == 1)
get_user_char( input )
But then whats the deal with needing -b and -a. are those my argv[1] and argv[3] and then each of those is followed by my binary number (argv[2]) and character string (argv[4]). Sorry I'm probably way off. I still really don't get how to put the command line arguments into my user input functions. It was said to be a simple thing but I don't understand it at all despite my hours of reading about it and asking TAs.
Let's see:
1) -b and -a are defined as constant string variables and word is defined as a string variable.
2) pos gets 2 so the while loop will keep looping until argc reaches 2. One question here is how do we set how many arguments argc holds?
3) The if and else if are basically detecting whether -b or -a was entered which determines which conversion is done, and that has to be [pos-1] because [0] is the command for invoking the program and [2] is the NULL?
4) Then the word = argv[pos] is giving word the string at the position argv[] is at? Or something like that maybe, hopefully.
5) Then pos += 2 resets pos back to 2 before the loop repeats.
2) argc is the count of arguments. It does not change. We set the pos to equal 2 at start. If the argc is at least 3, then the loop will do at least one iteration.
Since argc is at least 3, we know that argv[1] and argv[2] point to valid C-strings.
argv[pos-1] is same as argv[1], because pos is still 2.
If the user has written "./filename X Y Z", then argv[1] points to "X", argv[2] points to "Y", argv[3] points to "Z" and argc is 4.
3) If argv[2] is NULL, then argc is 2 and the loop is skipped altogether because (2<2) is false.
4) If argv[2] points to "Y", then word = argv[2]; does same as word = "Y";
Now you have something in std::string "word" just like your get_user_*** functions had a string after calling getline().
5) The pos += 2; is same as pos = pos + 2; The value of pos is incremented by 2.
The execution returns to line 11, where we test pos < argc again, i.e 4 < argc.
If that is true, then the argv[3] and argv[4] are also valid.
OK! Thank you. I'm starting to get it. So here's my new code. Now there's something wrong with my for loop in main. It keeps looping through and printing out my error message. No one i've asked in person can figure it out so maybe you can see what I'm doing wrong. Here's my new code: I'm at least happy it takes the arguments.
#include <iostream>
#include <string>
#include <cstring>
#include <bitset>
#include <sstream>
#include <algorithm>
usingnamespace std;
/**/
string char_to_bin( string bin_out ) // Convert ASCII to binary.
{
// A-B Conversion.
cout << "Your ASCII input in binary is: " << endl;
// size_t is an unsigned integral type that works with the sizeof operator.
for ( size_t i = 0; i < bin_out.size(); ++i )
{
// Prints binary values of the characters.
cout << bitset<8>( bin_out[i] );
// Bitset stores the characters into their bytes.
}
cout << endl;
return bin_out;
}
/**/
string bin_to_char( string char_out ) // Convert binary to ASCII.
{
// Allows the sequence of strings to be accessed directly as a string.
istringstream in( char_out );
// Divides the bits into bytes.
bitset<8> bs;
cout << endl << "Your binary input in ASCII is: ";
// B-A Conversion
// Loop extracts the bytes in the string and prints them as there ascii values.
while ( in >> bs )
{
cout << char( bs.to_ulong() );
}
cout << endl;
return char_out;
}
int main( int argc, char *argv[] )
{
argc = 5;
for ( int i = 0; i < argc; ++i )
{
if ( strcmp( argv[i], "-a" ) == 0 )
cout << char_to_bin( argv[++i] ) << endl;
if ( strcmp( argv[i], "-b" ) == 0 )
cout << bin_to_char( argv[++i] ) << endl;
else
cout << "I shan't put up with your insolence!" << endl;
}
return 0;
}
I shan't put up with your insolence!
Your ASCII input in binary is:
01110000011011110110111101110000
poop
I shan't put up with your insolence!
Your binary input in ASCII is: poop
01110000011011110110111101110000
I don't understand why it goes to the error message at all much less why it does it twice and first before my outputs. Thanks in advance. :)
Your loop initializes i=0. argv[0] is the name of the binary. argv[1] is the first command line parameter given by the user.
What was the input?
Note: On the last iteration i==argc-1 and if that argument is either "-a" or "-b", the ++i will dereference argv[argc] and although such pointer exists, it is a nullptr, so you do not want to use it.