C++ display char while loop rows - c++

I am very new to programming, so I apologize if this question seems absurdly simple. I am working on some extra questions in the current chapter of my C++ book. I have actually found a correct answer to the problem, but while doing so, I ran into a situation that is driving me crazy because I can't figure out WHY one particular solution works and another one doesn't.
So, the problem asks to print the ASCII values between 32 and 127 in a few rows with 16 characters per row. The solution I have come to (that works correctly) is this:
#include <iostream>
using namespace std;
int main()
{
char letter;
int count = 0;
for (letter = 32; letter < 127; letter++, count++)
{
if (count == 16)
{
cout << endl;
count = 0;
}
cout << letter << " ";
}
cout << endl;
return 0;
}
Again, the above code runs fine and does what I want it to. The difficulty lies in something I tried before this. I attempted to do the same problem with a nested while loop, like so:
#include <iostream>
using namespace std;
int main()
{
char letter = 32;
int count;
while (letter < 127)
{
count = 0;
while (count < 16)
{
cout << letter << " ";
letter++;
count++;
}
cout << endl;
}
cout << endl;
return 0;
}
This while loop just runs infinitely and also spits out some garbage after the ASCII characters I want, and I can't figure out why. What's even weirder is if I change the variable 'letter' in the code with while loops to an int instead of a char, it runs exactly the way I want it to and terminates when it should, just displaying the actual numbers instead of the ASCII values.
It's only when 'letter' is a char that I get an infinite loop. I'm sure it's something really simple, and I might just be too tired to see it right now, but any help/hints would be much appreciated! Even though I technically got the answer, it's driving me crazy that I don't know WHY the second answer fails so horribly.
Thanks in advance.

The answer is simple, true enough. Here is what happens - (signed)char can have values in the range [-128, 127] in the inner loop after you output the row up to 112, you increment count with another 16 and therefor you also increment letter with 16, this makes letter equal to 112 + 16 = 128, which due to the range of signed char is actually overflowing and becomes -128. So after this execution of the inner loop the condition of the outer loop still holds: -128 < 127. That is also why you get weird chars - these will be the values between -128 and 32.
How to fix the problem? Change the check in the inner loop:
while (count < 16 && letter < 127)

The inner while loop exits when letter == 48, 64, ..., 128. But as it is a (signed) char, 128 is interpreted as -128 and the outer loop will not terminate.
Change the inner loop to
while (count < 16 && letter < 127)
to get the same behavior as in your first example.
Or change letter to int, if it's OK to print all characters including 127:
int letter = 32;
...
cout << (char)letter << " ";

Try this code :
#include <iostream>
using namespace std;
int main()
{
int letter;
for (letter = 32; letter < 128; ++letter)
{
if (letter != 32 && letter % 16 == 0)
cout << endl;
cout << (char)letter << ' ';
}
}

Related

Adding to very large numbers using stack

i am a novice to C++ , I was trying to write this program for adding two very large numbers using strings but the program is not working correctly and I can't get what's wrong with it , please help me with this.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main() {
stack <char> a1;
stack<char> a2;
stack<int> result;
stack<int> temp;
int carry = 0;
string num1;
string num2;
cout << "Enter first number (both numbers should have equal digits)" << endl;
getline(cin, num1);
cout << "Enter second number" << endl;
getline(cin, num2);
for (int i = num1.size()-1; i >= 0; i--) {
a1.push(num1[i]);
a2.push(num2[i]);
}
while (!a1.empty() && !a2.empty()) {
int element = (int)a1.top() + (int)a2.top() + carry;
cout << element;
if (element > 10) {
element %= 10;
carry = 1;
}
result.push(element);
cout << result.top() << endl;
a1.pop();
a2.pop();
}
string abc;
while (!result.empty()) {
temp.push(result.top());
result.pop();
abc += temp.top();
}
cout << abc;
}
I know i have definitely made a logical mistake , but i can't get it , can anyone please guide me?
the following is the output am getting
I was thinking, why stacks should be used. My guess is that you did this, because the numbers must be processed from right to left.
Additionally, you have obiously a challenge with strings with a different length.
But both problems can be solved easily. Let us start with the different length strings.
If 2 strings have a different length, we can pad (fill in) the shorter string with leading `0's. How many leading '0s' do we need to add? Right, the delta of the lengths.
And for inserting characters in a string at a certain position, we have the function insert.
So, the code for that will look like this:
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
This is rather straightforward.
The result will always be 2 strings with equal length. With entering "1234" and "9", we will get: "1234" and "0009".
This makes the next task easier.
Now that we have 2 equal length strings, we can "add", like we learned in school.
We go from right to left, by starting with the highest possible index of a character in the string. This is always length-1.
For calculating the sum, we need first to subtract the ASCII code for '0' from the characters in the string, because the string contains not integer numbers, but characters. For example "123" consists of '1', '2', '3' and not of 1,2,3.
Suming up is then easy: digit + digit + carry.
The resulting digit is always the sum % 10. And the next carry is always sum / 10. Example 1: 3+5=8 8%10=8 8/10=0. Example 2: 9+8=17 17%10=7 17/10=1.
So, also this is rather simple.
After we worked on all digits of the strings, there maybe still a set carry. This we will then add to the string.
Adding digits will be done in any case using the instert function. Because we want to insert digits on the left side of the resulting string.
So, with working from right to left, using correct indices and the insert function, we do not have the need for a stack.
With a lot of input checking, the whole function would look like this:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Give instruction to user
std::cout << "\nPlease enter 2 positive interger numbers:\n";
// Here we will store the user input
std::string numberAsString1{}, numberAsString2{};
// Get strings from user and check, if that worked
if (std::cin >> numberAsString1 >> numberAsString2) {
// Check if all characters in string 1 are digits
if (std::all_of(numberAsString1.begin(), numberAsString1.end(), std::isdigit)) {
// Check if all characters in string 2 are digits
if (std::all_of(numberAsString2.begin(), numberAsString2.end(), std::isdigit)) {
// ---------------------------------------------------------------------------------
// Here we will store the calculated result
std::string result{};
// Temporary helpers
unsigned int carry{};
// ---------------------------------------------------------------------------------
// Make strings equal length. Pad with leading '0' s
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
// ---------------------------------------------------------------------------------
// Iterate over all digits from right to left
for (int i = numberAsString1.length()-1; i >= 0; --i) {
// Calculate the sum
const int sum = numberAsString1[i]-'0' + numberAsString2[i] - '0' + carry;
// Get the carry bit in case of overflow
carry = sum / 10;
// Save the resulting digit
result.insert(0, 1, sum % 10 + '0');
}
// handle last carry bit
if (carry) result.insert(0, 1, '1');
// ---------------------------------------------------------------------------------
// Show result
std::cout << "\n\nSum: " << result << '\n';
}
else std::cerr << "\n\nError: number 1 contains illegal characters\n";
}
else std::cerr << "\n\nError: number 2 contains illegal characters\n";
}
else std::cerr << "\n\nError: Problem with input\n";
return 0;
}

C++ string number of occurence

This is my first time asking something on stackoverflow, so I'm sorry if I fail in any aspect of building the topic etc...
So I'm a newbie at C++, I'm still at the beginning. I'm using a guide someone recommended me, and I'm stuck in a exercise which is about char and strings.
It's the following: They ask me to create a function that says the number of times that a certain word was repeated on a string.
I'll leave my code below for someone who can help me, if possible dont give me an obvious response like the code and then I just copy paste it. If you can just give me some hints on how to do it, I want to try to solve it on my own. Have a good night everyone.
#include <iostream>
#include <string.h>
#define MAX 50
using namespace std;
int times_occ(string s, string k) {
int count = 0, i = 0;
char word[sizeof(s)];
// while (s[i] == k[i])
// {
// i++;
// if (s[i] == '\0')
// {
// break;
// }
// }
for (i = 0; i <= sizeof(s); i++) {
if (s[i] == ' ' || s[i] == '\0') {
break;
}
word[i] = s[i];
}
word[i] = '\0';
for (i = 0; i <= sizeof(k); i++) {
if (word) {
if (k[i] == word[a]) {
a++;
count++;
}
}
}
cout << word << endl;
cout << count << endl; // this was supposed to count the number of times
// certain word was said in a string.
return count;
}
int main() {
char phrase[MAX];
char phrase1[MAX];
cin.getline(phrase, MAX);
cin.getline(phrase, MAX);
times_occ(phrase, phrase1);
}
Okay, first of all, the way you've used sizeof isn't really valid.
sizeof won't tell you the length of a string. For that, you want std::string::size() instead.
In this case, std::string is an object of some class, and sizeof will tell you the size of an object of that class. Every object of that type will yield the same size, regardless of the length of the string.
For example, consider code like this:
std::string foo("123456789");
std::string bar("12345");
std::cout << sizeof(foo) << "\t" << foo.size() << "\n";
std::cout << sizeof(bar) << "\t" << bar.size() << "\n";
When I run this, I get output like this:
8 9
8 5
So on this implementation, sizeof(string) is always 8, but some_string.size() tells us the actual length of the string.
So, that should at least be enough to get you started moving in a useful direction.
As #JerryCoffin mentioned, your word array has an invalid size. But - I want to make a more fundamental point:
Your code has two loops and a bunch of variables with arbitrary names. How should I know what's the difference between s and k? I even get k and i mixed up in the sense of forgetting that k is a string, not an integer. That kind of code difficult to read, and to debug. And we are a bit lazy and don't like debugging other people's code...
I suggest that you:
Have a very clear idea what your loops do, or what the different parts of your function do.
Create small self-contained functions - no more than one loop each please! - for each of those parts.
Use meaningful names for each function's parameters and for the local variables.
And then, if your program doesn't work - try debugging one function at a time.

Generate all natural numbers that have 3 digits whose 3rd digit - 1st digit=2nd digit

The problem's in the title.
If possible please give me exaplanations on what I did wrong and why correct solution is correct.
My attempt at solving it is in the code below... it was supposed get me all the 3 digit numbers then extract digit1, digit2 and digit3 from each number after which it should show the numbers that respect the digit3-digit1==digit2.
The program runs without errors but at the same time it doesn't really do anything.
#include <iostream>
using namespace std;
int main()
{
int Number,digit1,digit2,digit3,h;
for (Number=100; Number<=999; Number++)
{
h=Number;
}
digit1=h/100;
digit2=(h/10)%10;
digit3=h%10;
if (digit3-digit1==digit2)
cout<<digit1<<digit2<<digit3;
return 0;
}
The code that comes after the loop (other than return 0) has to go inside the loop. If it's outside the loop then it only works on the value 999, because that is the last value that h is set to before the loop exits. To print a new line you have to do cout << endl or just place << endl at the end of the print statement before the semicolon.
A few optimizations can be made here. You don't need to loop through all 899 numbers. Given the constraints the the third digit has to be greater than or equal to the first digit, so you can just run a loop for the first digit, and nested loop for the third digit that starts from the first digit.
for (int a = 1; a < 10; a++) {
for (int c = a; c < 10; c++) {
int b = c - a;
cout << a << b << c << endl;
}
}

I continually get a "Bus Error" while this is code is being executed?

The purpose of this code is to take a file that has been passed into the program and generate the letter frequency of each letter in the file. In above code, I remove punctuation and convert to lowercase letters.
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main()
{
string fileContent = "qr rqh zrxog kdyh eholhyhg lq wkh odvw bhduv ri wkh qlqhwhhqwk fhqwxub wkdw wklv";
int count[26] = { 0 }; // an array the size of the alphabet.
for(int f = 0; f < fileContent.length(); f++) // run til the file end.
{
if(fileContent[f] == 32) // to take care of the spaces.
{
f++; // also tried "continue;" and yeild different and also incorrect results.
}
if(fileContent[f] >= 48 && fileContent[f] <= 57) //take care of numbers.
{
f++; // tried "continue;"
}
count[fileContent[f]]++;
}
for(int p = 0; p < 26; p++)
{
cout << char(p + 97) << ": " << count[p] << endl;
}
return 0;
}
When I run this code I get some accurate frequencies, and some horribly incorrect ones (seems like every other result is wrong, yet after a few letters it trails off into astronomically large numbers). Any way to do this better? what is wrong with this code? As per request I have added some more of the code (including a string with a random 100 in it) as it was apparently not clear enough)
For more context, this program is for a Ceasar shift decoder I'm working on. I am in basic c++ and would greatly appreciate any advise from you more experienced devs. thank you!
In your program, this statement:
count[fileContent[f]]++;
should be:
count[fileContent[f]-97]++; //Assuming that all alphabets are in lowercase
If you do not do -97, it is trying to increase the value at index fileContent[f] of count array, which may be beyond the limit of count array.
Also, make sure to continue in both the if blocks and you don't need to do f++ explicitly in both the if blocks as in the for loop you are already doing f++.
You are doing things the difficult way: using C-style arrays, magic numbers in your code, and risking buffer overflows everywhere.
Compare your code to this:
#include <string>
#include <iostream>
#include <map>
using namespace std;
int main()
{
string fileContent = "qr rqh zrxog kdyh eholhyhg lq wkh odvw bhduv ri wkh qlqhwhhqwk fhqwxub wkdw wklv";
map<char, int> counts;
for (char ch : fileContent)
++counts[ch];
for (char ch = 'a'; ch <= 'z'; ++ch)
cout << ch << ": " << counts[ch] << '\n';
}
Or to print all the map contents (if you do not want to print 0 for letters that did not occur) you can use:
for (auto& item : counts)
cout << item.first << ": " << item.second << '\n';
Exercise for the reader to add in the code to exclude the spaces and numbers. Hint: look up the cctype header.

C++ for loop with char type

>The character 'b' is char('a'+1),'c' is char('a'+2),etc. Use a loop to write out a table of characters with their corresponding integer values.
I cannot finish this exercise because of this error.
error: lvalue required as increment operand
for(char a='a'; a<24; ++a)
{
cout<<char('a'++);
}
The loop body will never execute with the controlling expression a < 24 because you have initialized variable a with character a and all printable characters are not less than ASCII value 32.
Try this:
for(char a='a'; a < 'a' + 24; ++a)
{
cout << a;
}
I think you would be less confused if you named your variable letter instead of a, because it only represents the letter 'a' at the very beginning.
for(char letter='a'; letter<24; ++letter)
{
cout<<char('a'++);
}
I'm going to assume you actually want to print out the entire alphabet, not just the first 24 letters.
It looks from here like you tried to do a mix of two possible approaches. In the first approach, you increment a char from a to z with each iteration of the for loop and print it out each time. In the second approach, you increment some offset from 0 to 25 and print out 'a' + offset.
You mix these two approaches up in the first line. You're starting the loop with letter set to 'a', which you do not know the numerical value of. You then compare letter to see if it is less than 24. Well in any ASCII-compatible character set, the character 'a' has value 97, so this condition will never pass.
You then misuse ++ on the cout line. The ++ operator attempts to modify its operand, yet 'a' is a literal and so cannot be modified. Have a look at what your assignment told you. You can do 'a' + 1 to get 'b', for example, so this assumes you have an offset (which you don't with your current approach).
So to repeat, you have two options. First: keep letter as a char starting at 'a' and fix the condition so that it checks if letter is less than or equal to the value of 'z' and then just print out letter. Second: change letter to offset and start it off at 0 and increment it while it is less than 26, and then print out 'a' + offset.
Note, however, that both of these approaches assume that the letters have consecutive values in the execution character set. This is not necessarily true.
The ++ operator is a "hidden assignment" (the operand's value is changed by it). But you can only assign to variables, which 'a' is not.
I know this has been closed for a while but since the exercise was about while loops and not for loops, I thought I would offer my solution. I'm just going through the book myself and someone in the future might stumble over this.
int i = 0;
char n = 'a'; // this will list the alphabet
int conv = 0;
conv = n; // this converts the alphabet into integer
while (i < 26) { // starts from 0 and goes to 25
cout << char(n + i) << '\t' << conv + i << '\n';
++i;
}
You may use the following: (http://ideone.com/akwGhl)
#include <iostream>
int main()
{
for (char c = 'a'; c <= 'z'; ++c) {
std::cout << "letter " << c << " has value " << int(c) << std::endl;
}
return 0;
}
hey through troubleshooting i obtained a sample that worked , i have yet to perfectly understand how my code works but as the solutions that were proposed to me here seemed too technical for my level i figured that i should publish mine
#include"header files . h"//i use the libraries given in the book
int main () {
char a ='a';
int i = 0 ;
while (i <= 25)//for (i = 0 ; i <= 25 ; i++)
//for those who used for
{
cout << a << '\t' << 'a' + i << endl;
a += 1; // augments the character value of a to b ... then to z
i++; // augments the value of i allowing us thus to make the augmentation,if you are using the for structure do not put I in your code
}
}