make user enter a string of integers and output a different string - c++

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.

Related

Trying to read a single character at a time into an array of indefinite size

I am a CS student working on a c++ project. We have been instructed to declare a struct and use it to read in an array of chars and keep a tally of how many letters are used in the string. We are not allowed to use a string; it MUST be an array of our declared struct.
The input must be as long as the user wants; the code has to be able to accept new lines of input and be terminated by '.'
I'm really struggling here. I don't even know where to begin. I've thrown together some code as best-guess for what to do, but it crashes after pressing "." then enter, and I don't know why.
//declare struct
struct data
{
int tally = 0;
char letter;
};
//size of string to read in at a time
const int SIZE_OF_CHUNK = 11;
int main()
{
//input chunk of struct
data input[SIZE_OF_CHUNK];
int placemark,
length;
cout << "Enter sequence of characters, '.' to terminate:" << endl;
do
{
for (int index = 0; (input[index].letter != '\0') && (input[index - 1].letter != '.'); index++)
{
cin >> input[index].letter;
placemark++;
}
//I intend to put something here to handle if the code
needs to read in another chunk, but I want to fix the crashing
problem first
}
while (input[placemark].letter != '.');
//print out what was read in, just to check
for (int index = 0; input[index].letter != '\0'; index++)
{
cout << input[index].letter;
}
return 0;
}
I've tried looking up how to read in a single character but haven't found anything helpful to my circumstances so far. Any tips on what I'm doing wrong, or where I can find helpful resources, would be very much appreciated.
Are you sure you must use a declared struct?
If you just want to count the number of times a character has appeared, you don't need to store the character; you just need to store the number of times it appeared. So just unsigned lettersCount[26], and each index maps to a letter (i.e. index 0 means a, index 1 means b). Whenever a letter appears, just increase the count of that index.
You can map a letter to the index by making use of ASCII. Every letter is represented by a decimal number that you can look it up at ASCII table. For example, the letter a is represented by the decimal value 97, b is 98 and so on. The number increases successively, which we can make use of. So if you want to map a letter to an index, all you need to do is just value - 97 or value - 'a'. For example, if you read in the letter a, take away 97 from that and you'll get 0, which is what you want. After getting the index, it's just a simple ++ to increment the count of that letter.
Regarding the treatment of uppercase and lowercase (i.e. treat them the same or differently), it'll be up to you to figure it out how to do it (which should be fairly simple if you can understand what I've explained).

Null terminator carrying through when indexing string

I am trying pull specific characters from a string array, and assign them to defined indices in a new variable. I am having issues with what I expect is the null terminator, as there appear to be random assortment of undefined characters at the end of my strings.
I am new to coding in C++, and lower level programming in general. Note that the function "charBi" works perfectly, but it no longer works when assigning the output of "charBi" to the variable "binar" in the "strBi" function. I realize the code is probably not great, but any help is welcome, especially as it relates to getting rid of the random characters at the end of my "binar" string.
Thanks!
#include <iostream>
#include <array>
using namespace std;
//Program meant to output a string of binary for an input word or phrase
//library of letter and binary pairs
char letterNumber[27][10]={"A01000001","B01000010","C01000011","D01000100","E01000101","F01000110","G01000111",
"H01001000","I01001001","J01001010","K01001011","L01001100","M01001101","N01001110",
"O01001111","P01010000","Q01010001","R01010010","S01010011","T01010100","U01010101",
"V01010110","W01010111","X01011000","Y01011001","Z01011010"," 01011111"};
//finds binary number associated with input character. One character input
string charBi(char inputVar){ //WHY DOES THIS ONLY WORK IF THE FUNCTION IS A STRING?
//loop setup
int n=0;
int last=sizeof(letterNumber)/sizeof(letterNumber[0]); // equal 27
//loops through each of the strings in letterNumber
while (n!=last) {
if (letterNumber[n][0]==inputVar){ // if the letter is equal to input letter
char bina[8]; //number of numbers following a letter
for(int i=1;i<9;i++){ // writes the number associated with the letter to bina
bina[i-1]=letterNumber[n][i]; // assigns number to specific index
}
return bina; //BINA DEFINED AS CHAR, BUT OUTPUTTING AS STRING
}
n++;
}
}
//forms binary string of numbers for input phrase
string strBi(string strg){ //WHY DOES THIS ONLY WORK IF THE FUNCTION IS A STRING?
char binar[8*strg.length()]; //binary for each character is 8 numbers long
for(int i=0;i<strg.length();i++){ // for every letter in the input phrase
string chbi=charBi(strg[i]); //gets binary for individual letter from charBi function
cout<<"charbi sends: "<<chbi<<endl; //for debugging
for(int n=0;n<8;n++){ //for every 1 or 0 in the binary for an idividual letter
binar[(8*i)+n]=chbi[n]; // assign in order to string binar
}
cout<<"binar updates to: "<<binar<<endl; //for debugging
getchar(); //for debugging
}
return binar; //BINAR DEFINED AS CHAR, BUT OUTPUTTING AS STRING
}
int main(){
cout<<"final string is: "<<strBi("HELLO WORLD");
return 0;
}
Since you didn't properly terminate your arrays, the program is undefined.
In order to store a k-letter string, you need to use a k+1-element array and terminate it – char bina[9] = {}; and char binar[8*strg.length() + 1] = {}; should do the trick.
But you can simplify things a bit by leaving C behind:
std::map<char, std::string> letterNumber =
{{'A', "01000001"},
{'B', "01000010"},
// ...
{' ', "01011111}"}};
//forms binary string of numbers for input phrase
std::string strBi(const std::string& strg)
{
std::string binar;
binar.reserve(8 * strg.size());
std::for_each(strg.begin(), strg.end(), [&binar](char c) { binar += letterNumber[c]; });
return binar;
}
Make binar one character longer (char binar [8 * strg.length() + 1];) and set the last character to NUL (just before returning, do binar[8 * strg.length()] = '\0';)

Why it works when I type multiple characters in a character variable?

I am a new C++ user.
My code is as following:
#include <iostream>
using namespace std;
int main()
{
int option = 1;
char abstract='a';
while(option == 1){
char temp;
cin>> temp;
abstract = temp;
cout << abstract;
option = 1;
if(abstract == '!'){
option = 0;
}
}
return 0;
}
And when I typed something like: abcdefg
all the characters are on the screen,why? It's just because of the compiler?
In fact, only one character at a time is stored in your char. cin>>temp; reads a single char at a time since more characters would not fit there. The loop simply reads and prints one character after the other.
As a visualization hint, try echoing your characters with cout<<abstract<<endl;. You will see a single character per line/iteration.
Your terminal does not restrict the number of characters typed in , that's why you can type as many as you want. Your c++ compiler would read only one of the characters because 'temp' is of type char. you can type an 'if' statement to check the number of characters typed in the terminal
Because of the while loop, which processes each character in turn. Not sure what you expected to happen.
Print it out with delimiters to see that there's never more than a single character printed per iteration:
cout << "'" << abstract << "'";
The terminal window itself is responsible for reading the characters and echoing them back to the screen. Your C++ program asks the terminal for characters and, in this sort of program at least, has no effect on how those characters are displayed.

Generate numbers /c /wpa2

I want to generate 20 character wpa2 key, which consists of only numbers between 1- 10,000,000,000,000,000,000 in C++. Output format of each key must be in 20 characters format, like:
00000000000000000001
00000000000000000002
00000000000000000003
00000000000000000011
12300000000099945611
and so on.
I have this code, but:
It doesn't keep the numbers generated descending in 20 character format.
for (int i=0;i<=10000000000000000000;i++){
cout << 10000000000000000000 -i<<"\n";
}
Those numbers r too big than(long) integer, so g++ compiler in linux shell also didn't want to execute, due to size of "10000000000000000000 -i".
In this particular case, why not just have a string, and increment the character at the lowest index, if it oveflows (> '9'), then increment the next character up. Repeat and rinse until finished.
So, something like this:
std::string s = '000';
std::string::size_type len = s.length()
while (s != "999")
{
cout << s << endl;
s[len-1] ++;
int i = len-1;
while(s[i] > '9' && i >= 0)
{
s[i] = '0';
i--;
s[i]++;
}
}
However, if you have a machine that does one loop of the above code 1,000,000,000 times a second, it will take 317 years to run through your sequence. So I hope you have plenty of time and are eating healthily.
Your compiler needs to support 64-bit integers, if you want to store this as a number. It may be supported as long long data type. Change i to unsigned long long, and change the number literal to 10000000000000000000ULL. Be careful that you don't cast these values down to int (accidentally or otherwise) or you will lose some data.
Looping through all those numbers is going to take years, literally.
If you simply want to generate a random 20 character WPA2 key, you should do something like this instead using built in functions:
#include <iostream>
#include <string>
#include <chrono>
#include <random>
#include <algorithm>
std::string get_key() {
// Define all allowed characters (a WPA2 key can also contain letters).
std::string chars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
// Shuffle the characters.
std::mt19937 g(std::chrono::system_clock::now().time_since_epoch().count());
std::shuffle(std::begin(chars), std::end(chars), g);
// Return the first 20 characters.
return chars.substr(0, 20);
}
int main() {
std::cout << get_key() << std::endl;
}
If you only want a key consisting of numbers then remove all alpha characters from chars.

ASCII and isalpha if statement issue

I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC