How do I count the number of indexes used in an array - c++

Write a program that asks the user to enter their name. First Name and Last Name are entered separately by the user. The program then tells the following:
• Which part (First name, or Last name), has more character, and how many more characters.
• Total number of vowels used in the complete name.
• Tells the user if the First Name and Second Name are same.
This is my assignment and we cannot use strings library. We are supposed to use the character arrays to go about doing this.
Up till now I haven't been able to understand how can I figure out the number of indexes I use to store characters.
int count = 0;
cout << "Enter you first name: ";
char arr[10];
cin.getline(arr, 10);
for (int i = 0; i < 10; i++) {
if (arr[i] != ' ') {
count++;
}
else {
break;
}
}
int x= sizeof(arr) / sizeof(arr[10]);
cout << arr;
cout << endl << count<< endl<<x;
return 0;
but still I haven't come around to a solution.

I was using the wrong character for comparison. I should have used \0 but I was using ' '.
for (int i = 0; i < 10; i++) {
if (arr[i] != '\0') {
count++;
}
else {
break;
}
}

Related

Code outputs random symbols, i'm unsure what is wrong

I've made a program that shortens full names to initials, and removes any spaces between what has been entered. It did work before but now it prints the initials but also random symbols? I can't really figure out why it's doing it. I'm new to programming also.
This is my code:
// This code removes the spaces from the inputted name
char *removeSpaces(char *str)
{
int i = 0, j = 0;
while (str[i])
{
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
// This code takes the users name, and shortens (sh) it
int main(void) {
char str[100],sh[20];
int j=0;
cout<<"Enter Full Name :";
cin.getline(str,30);
for(int i=0;i<strlen(str);i++)
{
if(i==0){
sh[j]=str[i];
sh[++j]=' ';
}
else if(str[i]==' '){
sh[++j]=str[i+1];
sh[++j]=' ';
}
}
// This then takes the remove spaces code, and prints the initials with a new line
cout << removeSpaces(sh) <<endl;
cout << "\n" <<endl;
return 0;
}
Picture of the output
You are missing adding string terminator character ('\0') to string sh. Below is the program.
#include <stdio.h>
char *removeSpaces(char *str)
{
int i = 0, j = 0;
while (str[i])
{
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
// This code takes the users name, and shortens (sh) it
int main(void) {
char str[100],sh[100];
int j=0;
cout<<"Enter Full Name :";
cin.getline(str,30);
for(int i=0;i<strlen(str);i++)
{
if(i==0){
sh[j]=str[i];
sh[++j]=' ';
}
else if(str[i]==' '){
sh[++j]=str[i+1];
sh[++j]=' ';
}
}
sh[j+1] = '\0';
// This then takes the remove spaces code, and prints the initials with a new line
cout << removeSpaces(sh) <<endl;
cout << "\n" <<endl;
return 0;
}
Enter Full Name :ra me ge
rmg
You have missed out a line (I guess) after the for loop in your main function, which means your string is potentially not null-terminated.
Using the same (correct) logic you have in your removeSpaces function, just add this line immediately after the for loop in main:
sh[++j] = '\0';
You don't terminate sh with \0 after you're done, yet removeSpaces() expects a null character at the end of the string. Because of this, removeSpaces() could go past your intended boundary.
Just add this line after your for in main():
sh[++j] = '\0\;
Word of warning: You should always make sure that j is < 20 (the size of sh) before you set it. Otherwise, you could go past the boundary of sh. That could also become a source of problems.

Q: C++ - Reversing a string (sentence and word) using a class

For my code, I am trying to create a class with two functions that:
Display a cstring where each word is reversed
Display an entire cstring reversed
My two test sentences are "Hi There" and "To Be", so the output is:
erehT iH
eB oT
iH erehT
oT eB
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
class cStringType {
public:
char sentenceInput[80]; //Member variable
void reverse_sentence(); //Member function
void reverse_words(); //Member function
}; //Bottom of cStringType
int main()
{
cStringType sentence1, sentence2;
//Objects declared of cStringType
cout << "Please enter a sentence!\n" << endl;
cin.get(sentence1.sentenceInput, 79, '\n');
cin.ignore(80, '\n');
cout << "\nPlease enter another sentence!\n" << endl;
cin.get(sentence2.sentenceInput, 79, '\n');
cout << "\nThe first sentence reversed: ";
sentence1.reverse_sentence();
cout << endl;
cout << "The second sentence where each word is reversed: ";
sentence2.reverse_words();
cout << endl;
cout << endl;
cout << "The first sentence where each word is reversed: ";
sentence1.reverse_words();
cout << endl;
cout << "The second sentence reversed: ";
sentence2.reverse_sentence();
cout << endl;
return 0;
}
void cStringType::reverse_sentence()
{
char reverse_sentence;
//Reverse entire sentence using loop
for (int i = 0; i < strlen(sentenceInput) / 2; i++)
{
//Reverse the sentence using the length of the
//variable in the class
reverse_sentence = sentenceInput[i];
//First get the user input
//Set your variable equal to the variable in the class
sentenceInput[i] = sentenceInput[strlen(sentenceInput) - i - 1];
//Then reverse the characters and word order
//Starts from the last character in the array
//and goes backwards to 0
sentenceInput[strlen(sentenceInput) - i - 1] = reverse_sentence;
//Set the variable equal to the result
//sentenceInput is now the reverse of the user input in main
}
cout << sentenceInput << endl;
//Output of the new sentence
}
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
for (beginning = j, end = i - 1;
beginning < (i + j) / 2; beginning++, end--)
//j is the beginning of the array; increases
//i is the end of the array; decreases
{
reverse_words = sentenceInput[beginning];
//Set a variable equal to the first
//word in the original user input
sentenceInput[beginning] = sentenceInput[end];
//Set the first letter of a word equal to
//the last letter of a word
sentenceInput[end] = reverse_words;
//Set the result equal to the variable
//sentenceInput is now the user input where each
//word is reversed
}
}
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}
When I try to run the code, the output becomes something like this:
Please enter a sentence!
Hi There
Please enter another sentence!
To Be
The first sentence reversed: erehT iH
The second sentence where each word is reversed: oT eB
The first sentence where each word is reversed: There Hi
The second sentence reversed: Be To
I tried fixing it, but to no avail. The output is never correct.
Is there some way to fix this issue? Or better yet, to simplify the code? I believe the issue is with the code in the function.
The main problem with your code is that it's using the same buffer for both transformations. In other words: you are reversing the words in the same string which you've already reversed entirely. So you need to have another copy of the original string to do these independently.
Regarding simplifying your code you need to define a function that would reverse a string given a pointer and size or begin and end pointers. Then you can use this function on your entire string or on every word you find while searching for a space character:
char *begin = sentenceInput; //points to the beginning of the word
char *end = sentenceInput + strlen(sentenceInput);
for (char *it = begin; it != end; ++it)
if (*it == ' ') {
reverse(begin, it);
begin = it + 1;
}
reverse(begin, end); //reverse the last word
The reverse function can be either std::reverse, which can be used in the above code and on the entire string as follows:
std::reverse(sentenceInput, sentenceInput + strlen(sentenceInput))
or you can create a similar function like this:
void reverse(char *begin, char *end)
{
--end; //point to the last character instead of one-past-last
while (begin < end)
std::swap(*begin++, *end--);
}
I would suggest using stack for it, it is a natural way of looking at it.
so
#include <stack>
and then the function would be like that
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
stack<char> lastWord;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
//we want to print the last word that was parsed
while(!lastWord.empty())
{
//we print in the reverse order the word by taking off the stack char by char
cout<< lastWord.top();
lastWord.pop();
}
cout<<" ";
}
//if the letter is not space or end of string then push it on the stack
else
lastWord.push(sentenceInput[i]);
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}

Stuck with an infinite loop and whitespaces detection c++

This is the question that needs to be implemented:
Write a C++ program that stops reading a line of text when a period is
entered and displays the sentence with correct spacing and capitalization. For this program, correct spacing means only one space between words, and all letters should be lowercase, except the first letter. For example, if the user enters the text "i am going to Go TO THe moVies.", the displayed sentence should be "I am going to go to the movies."
I have written my piece of code which looks like this:
// Processing a sentence and verifying if it is grammatically correct or not (spacing and capitalization)
//#include <stdio.h>
//#include <conio.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence;
cout << "Enter the sentence: ";
getline(cin, sentence);
int len = sentence.length();
// Dealing with capitalizations
for (int j = 0; j <= len; j++)
{
if (islower(sentence[0]))
sentence[0] = toupper(sentence[0]);
if(j>0)
if(isupper(sentence[j]))
sentence[j] = tolower(sentence[j]);
}
int space = 0;
do
{
for (int k = 0; k <= len; k++)
{
if(isspace(sentence[k]))
{
cout << k << endl;
int n = k+1;
if(sentence[n] == ' ' && n <=len)
{
space++;
cout << space <<endl;
n++;
cout << n <<endl;
}
if(space!= 0)
sentence.erase(k,space);
cout << sentence <<endl;
}
}
len = sentence.length();
//cout << len <<endl;
} while (space != 0);
}
With this I was able to deal with capitalization issue but problem occurs when I try to check for more than one whitespace between two words. In the do loop I am somehow stuck in an infinite loop.
Like when I try and print the length of the string (len/len1) in the first line inside do-while loop, it keeps on running in an infinite loop. Similarly, when I try and print the value of k after the for loop, it again goes into infinite loop. I think it has to do with my use of do-while loop, but I am not able to get my head around it.
This is the output that I am receiving.
there are a few different issues with this code, but i believe that the code below addresses them. hopefully this code is readable enough that you can learn a few techniques. for example, no need to capitalize the first letter inside the loop, do it once and be done with it.
the usual problem with infinite loops is that the loop termination condition is never met--ensure that it will be met no matter what happens in the loop.
#include <iostream>
#include <string>
using namespace std;
int main() {
string sentence;
cout << "Enter the sentence: ";
getline(cin, sentence);
int len = sentence.find(".", 0) + 1; // up to and including the period
// Dealing with capitalizations
if (islower(sentence[0]))
sentence[0] = toupper(sentence[0]);
for (int j = 1; j < len; j++)
if(isupper(sentence[j]))
sentence[j] = tolower(sentence[j]);
// eliminate duplicate whitespace
for (int i = 0; i < len; i++)
if (isspace(sentence[i]))
// check length first, i + 1 as index could overflow buffer
while (i < len && isspace(sentence[i + 1])) {
sentence.erase(i + 1, 1);
len--; // ensure sentence decreases in length
}
cout << sentence.substr(0, len) << endl;
}
Here goes
std::string sentence;
std::string new_sentence;
std::cout << "Enter the sentence: ";
std::getline(std::cin, sentence);
bool do_write = false; // Looking for first non-space character
bool first_char = true;
// Loop to end of string or .
for (unsiged int i = 0; i < sentence.length() && sentence[i] != '.'; ++i) {
if (sentence[i] != ' ') { // Not space - good - write it
do_write = true;
}
if (do_write) {
new_sentence += (first_char ? toupper(sentence[i]) : tolower(sentence[i]);
first_char = false;
}
if (sentence[i] == ' ') {
do_write = false; // No more spaces please
}
}
if (i < sentence.length()) { // Add dot if required
new_sentence += '.';
}

Beginner c++ array and loop?

Trying to reverse the order of the characters input. I'm getting really close but no cigar.
#include <iostream>
using namespace std;
const int MAX = 10;
int main()
{
char a[MAX], next;
int index = 0;
cout << "Please enter in up to 10 letters ending with a period: " << endl;
cin >> next;
while((next != '.') && (index < 10))
{
a[index] = next;
index++;
cin >> next;
//cout << " " << next << endl;
}
int numbers_used = index;
for(index = 0; index <= numbers_used; index++)
{
a[index] = a[numbers_used -1];
numbers_used--;
cout << a[index] << " " << endl;
}
}
I'm getting everything but the last switch and even though my code is not as clean I'm failing to see where I'm going wrong.
The book code is:
for(index = numbers_used -1; index >= 0; index--)
cout<<a[index];
cout<< endl;
and why is it index = numbers_used - 1 ?? Since numbers_used was set to index and index was initialized at 0 and not 1 wouldn't I want to run the loop "numbers_used" amount of times? What am I missing?
Try this:
char* flip(char* str, int len) {
for(int x=0; x<(len/2); x++) {
swap(str[x], str[len-x-1]);
}
return str;
}
As of right now, after you get to the middle of the string, you'll have overwritten the values that you would need to copy to the second half. With a string like "FooBarBiz", your code will produce the following over iterations (I've put spaces in to try and make things clearer):
1: FooBarBiz
2: z ooBarBiz
3: zi oBarBiz
4: ziB BarBiz
5: ziBr arBiz
6: ziBra rBiz
7: ziBrar Biz
...
The code I posted however, uses the c++ swap function to swap the complimentary values, that way there are no lost values (we're not doing any overwriting), and you won't need to store the whole string in a placeholder variable. Does this make sense?
If you want to reverse the list you have to start from the last element and decrease the index .
You can approach this in at least two different ways. You can reverse the order of the string and then print, or you can leave the original string unmodified and simply print in reverse. I'd recommend the latter approach, in which case all you'd need to do is to change your last for loop to this:
for(index = 0; index < numbers_used; index++)
{
cout << a[numbers_used-index-1] << " " << endl;
}
Wouldn't it be easier this way ?
#include<iostream>
#include<string>
using namespace std;
const int MAX = 5;
int main()
{
char a[MAX], next;
int index = 0;
bool period = false;
cout << "Please enter in up to 10 letters ending with a period: " << endl;
for(int i = 0; i < MAX && !period; i++)
{
cin >> next;
if(next != '.')
{
a[i] = next; // put the value into the array
index++;
}
else
period = true;
}
for(int i = index - 1; i >= 0 ; i--)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
The problem can be solved by using the iterators from the standard library. The BidirectionalIterator as for example offered by std::string, std::list or std::vector can be traversed in both directions.
Using a std::string the solution could be:
#include <iostream>
#include <string>
using namespace std;
int main(int, char**) {
char n = 0;
string a;
while (n != '.' && a.size() < 10) {
cin >> n;
if (n != '.') {
a.push_back(n);
}
}
for (string::reverse_iterator it = a.rbegin(); it != a.rend(); ++it) {
cout << *it << endl;
}
}
I will start by saying: use std::string instead of C-style strings - it's universally less messy and more flexible.
Still, let's go with C-style strings since that's how you are attempting to do it and apparently your textbook also.
I won't comment on the way the user input is read, because I'm not sure if it's copied from the textbook (yikes!!) or you've done it yourself either way I find it to be pointless and wrong because it can lead to several problems. Note that the given book solution only prints out the characters in the reversed order and doesn't reverse the character array itself. You are apparently trying to reverse it.
Your solution is decrementing the numbers_used variable inside the for loop itself. This is a very bad idea since that variable is used in the conditional statement of the for loop. This means the loop will stop before it has iterated over the whole array. Even if the loop worked properly you still wouldn't have reversed the array since once this line executes
a[index] = a[numbers_used -1];
the original value of a[index] is overwritten and forgotten.
I'll try and write a simple solution to reverse a character array for a beginner:
#include <iostream>
#include <cstring> //getline, strlen
using namespace std;
const int MAX_LETTERS = 10;
int main() {
char a[MAX_LETTERS + 1]; //since it's zero terminated
cout << "Enter at most " << MAX_LETTERS << "characters (anything over " <<
MAX_LETTERS << " will be truncated):\n";
cin.getline(a, MAX_LETTERS + 1);
int length = strlen(a); //returns length of input
int last_char = length - 1;
//reverse array
for (int i = 0; i < length / 2; i++) {
char temp = a[i];
a[i] = a[last_char];
a[last_char] = temp;
last_char--;
}
//print array
for (int i = 0; i < length; i++)
cout << a[i];
return 0;
}
Read this tutorial on C style strings, it will help you a lot.
The last for loop in your code is
int numbers_used = index;
for(index = 0; index <= numbers_used; index++)
{
a[index] = a[numbers_used -1];
numbers_used--;
cout << a[index] << " " << endl;
}
If we consider 10 letters abcdefghij and according to your code the numbers_used=10after first loop.So in second loop
//In for loop
//index=0
a[index]=a[numbers_used-1]; // a[0]=a[9] => a[0]=j
numbers_used--; //numbers_used=9;
//index=1
a[index]=a[numbers_used-1]; //a[1]=a[8] => a[1]=i
numbers_used--; //numbers_used=8;
//index=2
a[index]=a[numbers_used-1]; //a[2]=a[7] => a[1]=h
numbers_used--; //numbers_used=7;
//index=3
a[index]=a[numbers_used-1]; //a[3]=a[6] => a[1]=g
numbers_used--; //numbers_used=6;
//index=4
a[index]=a[numbers_used-1]; //a[4]=a[5] => a[4]=f
numbers_used--; //numbers_used=5;
//index=5
a[index]=a[numbers_used-1]; //a[5]=a[5] => a[5]=e
numbers_used--; //numbers_used=4;
// index=6 and numbers_used becomes 4 => index <= numbers_used condition is violated
so you will out of for loop.
This is why u cant get through. And in the second code i,e in the Book.
for(index = numbers_used -1; index >= 0; index--)
cout<<a[index];
cout<< endl;
The numbers_used value is 10 but a[9] is the last value in the array so index is assigned to numbers_used-1. so that you can print from a[9] to a[0].

C++:array functions

How can I write a program that reads in, a collection of characters from the key board and outputs them to the console. Data is input at random, but output selectively. Only unique characters are displayed at the console. Therefore, every character should be displayed once, no matter how many times it appears in the array.
For example, if an array
Char letterArray[ ] = {B,C,C,X,Y,U,U,U};
The output should be:
B,C,X,Y,U
This is what I have done so far...
char myArray [500];
int count = 0;
int entered = 0;
char num;
while (entered < 8)
{
cout << "\nEnter a Character:";
cin >> num;
bool duplicate = false;
entered++;
for (int i = 0; i < 8; i++)
{
if (myArray[i] == num)
duplicate=true;
}
if (!duplicate)
{
myArray[count] = num;
count++;
} // end if
else
cout << num << " character has already been entered\n\n";
// prints the list of values
cout<<"The final Array Contains:\n";
for (int i = 0; i < count; i++)
{
cout << myArray[i] << " ";
}
}
I believe you could make use of std::set<>.
"Sets are a kind of associative container that stores unique elements <...> elements in a set are always sorted from lower to higher following a specific strict weak ordering criterion set"
Looking through your code...
char myArray [500];
Why 500? You never use more than 8.
char num;
Confusing naming. Most programmers would expect a variable named num to be a numeric type (e.g. int or float).
while (entered < 8)
Consider replacing 8 with a constant (e.g. const int kMaxEntered = 8;).
cin >> num;
cin might be line-buffered; i.e. it does nothing until a whole line is entered.
for (int i = 0; i < 8; i++)
{
if (myArray[i] == num)
duplicate=true;
}
You're accessing uninitialized elements of myArray. Hint: your loop size should not be 8.
Consider using continue; if you find a duplicate.
if (!duplicate)
{
myArray[count] = num;
count++;
} // end if
else
cout << num << " character has already been entered\n\n";
Your // end if comment is incorrect. The if isn't ended until the else is done.
You may want to add braces around the else clause, or remove the braces from the if clause by combining its two lines into the one-line myArray[count++] = num;.
// prints the list of values
cout<<"The final Array Contains:\n";
for (int i = 0; i < count; i++)
{
cout << myArray[i] << " ";
}
You're printing the list every time you get a single input?
Don't use \n in text to cout unless you specifically want to micromanage buffering. Instead, use endl. Also, always put spaces around binary operators like << and don't randomly capitalize words:
cout << "The final array contains:" << endl;
for (int i = 0; i < count; i++)
cout << myArray[i] << " ";
cout << endl;
It would be much more efficient to create an array of size 128 (assuming you are dealing with ASCII) that is initialized with false. Every time you get a character, check its ASCII value and if the array is true on that value you don't print it. After that, update the value of the array on the character value to true. Something like:
bool *seenArray = new bool[128]();
void onkey(char input) {
if(((int)input) < 0) return;
if (!seenArray[(int)input]) {
myArray[count] = input;
count++;
seenArray[(int)input] = true;
}
}