How do I check for a specific char within a string? - c++

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?

Related

Why when a character array is compared to another character array, output is wrong but when character array is compared to a string output is correct? [duplicate]

This question already has an answer here:
C++ string and string literal comparison
(1 answer)
Closed 1 year ago.
Question - The translation from the Berland language into the Birland language is not an easy task. Those languages are very similar: a berlandish word differs from a birlandish word with the same meaning a little: it is spelled (and pronounced) reversely. For example, a Berlandish word code corresponds to a Birlandish word edoc. However, it's easy to make a mistake during the «translation». Vasya translated word s from Berlandish into Birlandish as t. Help him: find out if he translated the word correctly.
Input -
The first line contains word s, the second line contains word t. The words consist of lowercase Latin letters. The input data do not consist unnecessary spaces. The words are not empty and their lengths do not exceed 100 symbols.
Output -
If the word t is a word s, written reversely, print YES, otherwise print NO.
When I write this code, the output is wrong -
int main(){
char s[100000],a[100000];
cin >> s >> a;
strrev(s);
if(s==a){
cout << "YES";
}else{cout << "NO";}
}
But when I write this code, the output is correct -
int main(){
char s[100000];
string a;
cin >> s >> a;
strrev(s);
if(s==a){
cout << "YES";
}else{cout << "NO";}
}
Why is it like this, is there a rule that a character array cannot be compared to another character array and if so, how can it be compared to a string?
Remember that arrays naturally decay to pointers to their first elements, and it's such pointers that you are comparing.
In short, what you're really doing is:
if(&s[0] == &a[0])
And those two pointers will never be equal.
To compare the contents of character arrays, you need to use strcmp() or similar function instead, eg:
if(strcmp(s, a) == 0)
Since you're programming in C++, please use std::string for all your strings. There are overloads for the == operator that do the right thing if you have std::string values.

Array conversion guidance

I'm stuck on an assignment which converts contents of an array (input from the user) to a pre-declared shorthand.
I want it to be as simple as strcpy(" and ", "+");
to change the word 'and' within a string, to a '+' sign.
Unfortunately, no matter how I structure the function; I get a deprecated conversion warning (variant loops, and direct applications, attempted).
Side note; this is assignment based, so my string shortcuts are severely limited, and no pointers (I've seen several versions of clearing the fault using them).
I'm not looking for someone to do my homework; just guidance on how strcpy can be applied without creating the dep. warning. Perhaps I shouldn't be using strcpy at all?
strcpy copies the contents of the second string into the memory of the first string. Since you're copying a string literal into a string literal it can't do it (you can't write to a string literal) and so it complains.
Instead you need to build your own search and replace system. You can use strstr() to search for a substring within a string, and it returns the pointer in memory to the start of that found string (if it's found).
Let's take the sample string Jack and Jill went up the hill.
char *andloc = strstr(buffer, " and ");
That would return the address of the start of the string (say 0x100) plus the offset of the word " and " (including spaces) within it (0x100 + 4) which would be 0x104.
Then, if found, you can replace it with the & symbol. However you can't use strcpy for that as it'll terminate the string. Instead you can set the bytes manually, or use memcpy:
if (andloc != NULL) { // it's been found
andloc[1] = '&';
andloc[2] = ' ';
}
or:
if (andloc != NULL) { // it's been found
memcpy(andloc, " & ", 3);
}
That would result in Jack & d Jill went up the hill. We're not quite there yet. Next you have to shuffle everything down to cover the "d " from the old " and ". For that you'd think you could now use strcpy or memcpy, however that's not possible - the strings (source and destination) overlap, and the manual pages for both specifically state that the strings must not overlap and to use memmove instead.
So you can move the contents of the string after the "d " to after the "& " instead:
memmove(andloc + 3, andloc + 5, strlen(andloc + 5) + 1);
Adding a number to a string like that adds to the address of the pointer. So we're looking at copying the data from 5 characters further on in the string that the old "and" location into a space starting at 3 characters on from the start of the old "and" location. The amount to copy is the length of the string from 5 characters on from the start of the "and" location plus one so it copies the NULL character at the end of the string.
Another manual way of doing it would be to iterate through each character until you find the end of the string:
char *to = andloc + 3;
char *from = andloc + 5;
while (*from) { // Until the end of the string
*to = *from; // Copy one character
to++; // Move to the ...
from++; // ... next character pair
}
*to = 0; // Add the end of string marker.
So now either way the string memory contains:
Jack & Jill went up the hill\0l\0
The \0 is the end of string marker, so the actual string "content" is only up as far as the first \0 and the l\0 is now ignored.
Note that this only works if you are replacing a part with something that is smaller. If you are replacing it with something bigger, so the string grows in size, you will be forced to use memmove, which first copies the content to a scratchpad, and ensure that your buffer has enough room in it to store the finished string (this kind of thing is often a big source of "buffer overruns" which are a security headache and one of the biggest causes of systems being hacked). Also you have to do the whole thing backwards - move the latter part of the string first to make room, then modify the gap between the two halves.

How to use loop variable within string (name)

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) + "]"

Trying to write a code the corrects a string sentence that is written inside out

I'm a software engineering student, and i need some help with an assignment i was given
i need a code that corrects a sentence written inside out
example;
i love programming
rp evol i gnimmargo
(what i mean by inside out .... that the sentence gets cut into half and each half is flipped)
i need to correct the scrambled sentence
i already started it by counting the charterers in the string that the user enters and cutting the sentence .... but i just cant figure out how to flip each half then join them
any ideas??
#include <iostream>
#include <string>
using namespace std;
//prototype
int NumberOfChar(string testCase);
int main()
{
// declaration
int N, halfCharNum, halfTestCase, size;
string testCase;
// input
cout<<"please enter an integer number, that will represent the number of test cases: "<<endl;
//cin>>N;
cout<< NumberOfChar(testCase)<<endl;
halfCharNum=size/2;
return 0;
}
int NumberOfChar(string testCase)
{
cout << "Enter your string: " <<endl;
getline(cin,testCase);
const int size=testCase.length();
cout << "The total number of characters entered is: " << endl;
return size;
}
This takes all of two lines of C++ code.
1) reverse the string (std::reverse)
2) Rotate the string left n characters where n is half the number of characters in the string. (std::rotate)
First, replace each element in the string with the element on the other end and work your way in.
i.e. in the string "rp evol i gnimmargo" exchange the first character "r" with the last character "o" and then work your way in, next exchanging "p" with "g" and so on.
That leaves you with "ogramming i love pr"
Then, swap the first and second halves of the string.
i.e. "ogramming i love pr" can be split into "ogramming" and " i love pr" -- just swap them for " i love pr" and "ogramming" and combine them
Just use a large dictionary of english words and implement an evolutionary algorithm. Might not be the shortest path to glory but definitely a fun task :-)
Sample dictionaries (you might need anyway) can be found
here,
here,
or here

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.