How to use loop variable within string (name) - c++

I am doing object oriented programming and I have to give different names (physBox1, physBox2..... physBox10) to 10 different boxes (represented by 10 element array Box[10]) in C++ language.
for (G4int i=0; i<10; i++)
{
new G4PVPlacement(0, Box[i],"phyBox[i]");
}
Here G4PVPlacement is some class which takes three values - second value is Box[i] indicating the 10 boxes and physBox[i] are names of that boxes. Here I am confused whether physBox[i] will be treated as a single string or here [i] can run from 0 to 9 according to "for loop".

"phyBox[i]" is a string literal, within which i is simply the letter i. If you want to make a string containing a run-time value, you'll have to do it yourself:
"phyBox[" + std::to_string(i) + "]"

Related

Error with big number of characters while making a letter pyramid

The task is to make a letter pyramid. I have done it but its behaviour goes very strange after I pass a certain number of characters that were inputed. Looking forward to an answer.
string input{};
string reverseString{};
getline(cin,input);
for(int j = input.length()-1;j>=0;j--){
reverseString += input.at(j);
}
for(int i = 0;i<input.length();i++){
int numberOfSpaces {};
numberOfSpaces = input.length()-i;
string spaces(" ",numberOfSpaces);
cout<< spaces << input.substr(0,i) << input.at(i)<<reverseString.substr(numberOfSpaces,i) <<spaces<<endl;
}
This is an example of the input/output:
string spaces(" ",numberOfSpaces);
This doesn't do what you think it does.
This constructor takes an array and a count.
It copies count (in this case numberOfSpaces) items from the passed in array.
The passed in array has length 1 (technically 2 with the null terminator), and so anything > 2 will cause undefined behaviour as it reads off the end of the array.

How do I check for a specific char within a string?

Disclaimer: I am super new to c++ and programming in general.
I have a function that takes in a string parameter that is only 2 integers long. I want to use the first and second int of the parameter to index into the chessBoard[8][8] to select a space on the board. Each index (space) in the 2D array (board) contains a char representing a piece type.
The function is supposed to determine the piece type, then call a move function for the specific piece.
Here is a part of the code applied to the king piece.
int movePiece(string startPos) {
string pieceType = chessBoard[startPos[0]][startPos[1]];
cout << chessBoard[startPos[0]][startPos[1]] <<endl;
if (tolower(pieceType) == 'k') {
kingMove(startPos);
}
Line 5 is a test to see what exactly is being returned. For some reason it prints a " " (space) which means it is comparing " " to 'k' or any of the other chars representing piece types. Yet I can put 'cout >> chessBoard[0][3]' and have it print a 'k' (the piece on that space on the board). A space is also returned for any space on the board, not just [0][3].
'startPos' is a string, so I should be able to use startPos[0] and startPos[1] with a stringstream to access the integers, right? What am I doing wrong?

How to get all initials of name stored in an array using 2 for loops?

The user inputs their full name into the console and gets stored in an array using getline(). The array that the name is stored in is of type "string"
The problem i am trying to solve is as follows:
Include a for-loop that counts the number of names in the full name
and then uses that information in a second for loop that displays the
full name formally.
So if the user enters in 'Paul Matthew Jones', I want the console to display 'PM Jones'.
There are a few restrictions for the question. I can't use any functions. I must use only 2 loops and I must only use 1 array.
for (int i = 0; i < myName.length(); i++)
{
if (myName[i] == ' ')
{
nameLength = nameLength + 1;
}
}
Split the input to individual strings in first place (e.g. using std::istringstream and a std::vector<std::string> to collect them).
Then just collect all of the first characters and concatenate these, besides for the last string in the split up strings collection which should be appended in whole, and prefixed with a ' ' character.

getline() Adding Character to Front of String? -- Actually substr syntax error

I'm writing a program that will balance Chemistry Equations; I thought it'd be a good challenge and help reinforce the information I've recently learned.
My program is set up to use getline(cin, std::string) to receive the equation. From there it separates the equation into two halves: a left side and right side by making a substring when it encounters a =.
I'm having issues which only concerns the left side of my string, which is called std::string leftSide. My program then goes into a for loop that iterates over the length of leftSide. The first condition checks to see if the character is uppercase, because chemical formulas are written with the element symbols and a symbol consists of either one upper case letter, or an upper case and one lower case letter. After it checks to see if the current character is uppercase, it checks to see if the next character is lower case; if it's lower case then I create a temporary string, combine leftSide[index] with leftSide[index+1] in the temp string then push the string to my vector.
My problem lies on the first iteration; I've been using CuFe3 = 8 (right side doesn't matter right now) to test it out. The only thing stored in std::string temp is C. I'm not sure why this happening; also, I'm still getting numbers in my final answer and I don't understand why. Some help fixing these two issues, along with an explanation, would be greatly appreciated.
[CODE]
int index = 0;
for (it = leftSide.begin(); it!=leftSide.end(); ++it, index++)
{
bool UPPER_LETTER = isupper(leftSide[index]);
bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);
if (UPPER_LETTER)// if the character is an uppercase letter
{
if (NEXT_LOWER_LETTER)
{
string temp = leftSide.substr(index, (index+1));//add THIS capital and next lowercase
elementSymbol.push_back(temp); // add temp to vector
temp.clear(); //used to try and fix problem initially
}
else if (UPPER_LETTER && !NEXT_LOWER_LETTER) //used to try and prevent number from getting in
{
string temp = leftSide.substr(index, index);
elementSymbol.push_back(temp);
}
}
else if (isdigit(leftSide[index])) // if it's a number
num++;
}
[EDIT] When I entered in only ASDF, *** ***S ***DF ***F was the output.
string temp = leftSide.substr(index, (index+1));
substr takes the first index and then a length, rather than first and last indices. You want substr(index, 2). Since in your example index is 0 you're doing: substr(index, 1) which creates a string of length 1, which is "C".
string temp = leftSide.substr(index, index);
Since index is 0 this is substr(index, 0), which creates a string of length 0, that is, an empty string.
When you're processing parts of the string with a higher index, such as Fe in "CuFe3" the value you pass in as the length parameter is higher and so you're creating strings that are longer. F is at index 2 and you call substr(index, 3), which creates the string "Fe3".
Also the standard library usually uses half open ranges, so even if substr took two indices (which, again, it doesn't) you would do substr(index, index+2) to get a two character string.
bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);
You might want to check that index+1 is a valid index. If you don't want to do that manually you might at least switch to using the bounds checked function at() instead of operator[].

C++ string manipulation / input

This is for homework! But I need help anyway. The assignment is to input a sentence then output the number of words, and the number of occurrences of each letter. The output must have the letters in alphabetical order. So far, I've been able to count the number of words and get all the letters to lower case so that I'll be able to keep count of them. My question is how to actually keep count of the letters.
Example of output:
I say Hi.
3 words
1 a
1 h
2 i
1 s
1 y
Here's the code that I have so far:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
int letters[26];
char letter;
int word = 0;
cout << "Please enter a sentence: "<< endl;
do
{
cin.get(letter);
if(isspace(letter))
word++;
letter = tolower(letter);
cout << letter;
}
while (letter != '\n');
cout << "The number of words = " << word << endl;
return 0;
}
Should I input directly into a C-string? or will that mess up the word count?
If you're allowed to use STL, use std::map for mapping letters to counters. It will additionally sort the letters.
Otherwise, treat chars as indexes in an array of counters and increment them.
My question is how to actually keep
count of the letters
It's fairly straight forward. Simply create an array of 26 integers, (one for each letter), and initialize it to zero.
int letters[26] = { 0 }; // Initialize array to zero
Each value in the array corresponds to a count of a particular letter. Array index 0 refers to 'a', array index 1 refers to 'b', and so on. Then, everytime you encounter a letter, increment the appropriate value in the array. You can use the character 'a' (ASCII value 97) as a starting offset. So, given the variable char letter; you would do:
++letters[tolower(letter) - 'a'];
But always make sure that before you increment the appropriate value in the array, you check that isalpha(letter) && islower(letter) to make sure that your letter is in the range of lowercase a-z; otherwise you will access an index beyond the bounds of the array. You can also test for this condition by saying if (letter >= 'a' && letter <= 'z').
Hint: tolower(letter)-'a' is:
0 if letter is a
1 if letter is b
...
Hm, just few points to make your home task more useful to you (and your code more correct):
Think what happens if you have file with several spaces in a row (word counting).
Think how to be more correct with 'letters' (check for isalpha() at least). Also isalpha() could be key for simpler counting with fixed array [256] (this might be even the best solution as for performance vs std::map usage, check std::map documentation anyway).
Think about more effective file input. At least line at once.