Adding to array only adds 1 value, then stops - c++

I am trying to make a function that converts a TCHAR array to individual arrays, splitting it by a comma, then add a null terminator character (I think that is the name, it is '\0' in regEx). (Basically, the .split function in java, + a '\0'), but the code is only adding one value, then stops. It is very weird, as I believe this worked ~3-4 months ago, but not now for a reason unknown.
I would imagine it is an issue with my conceptual understanding of C++, as it is very much not my language of choice.
My apologies that this is basically asking someone to "fix my homework" (not actually homework, just a side project). However, I can't find the issue and have been unable to find the error for a few hours now, again probably due to me being dumb with C++.
Code Sample:
TCHAR** schemeValueToArray(TCHAR* buffer, DWORD size) {
TCHAR delim = ',';
TCHAR** out = new TCHAR*[CURSORS_AMOUNT];
int lastSeperator = 0;
for (int outOn = 0; outOn < CURSORS_AMOUNT-1; outOn++) {
// Get rest of section until end
TCHAR* temp = new TCHAR[size];
for (int i = 0; i < size; i++) {
if (buffer[i + lastSeperator] == ',') {
temp[i] = '\0';
out[outOn] = temp;
lastSeperator += i;
lastSeperator++;
break;
}
temp[i] = buffer[i + lastSeperator];
}
}
return out;
}
If you would like a bigger snippet, I can provide it.
Also, if it helps, this project once would change my mouse cursor theme when an app called AutoDarkMode requested. Making my cursor light theme during the day and dark theme at night. It would do this by copying the Registry theme value, splitting it, then putting the correct files in the correct registry spots. It was a small thing that I really liked, and now in explicitly, it has stopped.
Also, also, I am a lot more familiar with Java and Kotlin. If you are looking for ways to describe something and can relate it to something in those languages, I should be able to understand.
Thank you guys, appreciate any help!

If at all possible, I'd switch to using something like an std::vector<std::string> instead of pointers to pointers and such.
std::vector<std::string> schemeValueToArray(TCHAR* buffer) {
std::istringstream buf(buffer);
std::vector<std::string> ret;
std::string item;
while (std::getline(buf, item, ',')) {
ret.push_back(item);
}
return ret;
}

Related

How would I print the index of an array? C++

I was just wondering how do I print off the Index position of an array? I know there's an if loop involved but I just can't seem to understand it properly.
I want the code to be able to print off what the element of the Array is and the position number. I should also mention that this is for a function as well. Any help will be appreciated. Below is my code
int index_of(string names[], int size)
{
string name;
int index;
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return;
}
}
}
What you are trying to do is called "searching".
You have a string which (potentially) is the known content of an entry in an array, but at an unknown index.
What you need to do is to find the index which, used for accessing the entry at that index, yields content which is identical to what you are looking for.
The code you show is more or less pseudo code for doing exactly that.
However, the shown code will not work for the following reasons:
it does not correctly return the index in question, it should return i;
it only returns explicitly in case of finding something, it should, after the loop, return -1;(as a proposal how to communicate failure)
it incorrectly compares (the == operator cannot meaningfully be used on "strings", which in C are only pointers to characters), it should use strncmp(), see e.g. https://en.cppreference.com/w/c/string/byte/strncmp
it does not actually print anything, but I think that is a problem of phrasing your goal and you can easily add a print outside of the shown code, using the (now hopefully correct and correctly returned) return value of the shown function
it has the problem mentioned by Nathan Pierson, see their comment/answer
This is what managed to print the indexes, you guys were actually able to help me understand what I was doing
int index_of(string names[], int size, string name)
{
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return i;
}
return -1;
}
}

Split a even-numbered string in c++

I am very new to c++. I am trying to split a string that contains even numbered sub strings till there is no even numbered sub string left. For example, if I input AB ABCD ABC, the output should be A B A B C D ABC. I am trying to do it without tokens, because I don't know how to..
What I have so far only split the first even sub string and it doesn't work if I only have 1 sub string. Can someone please help me out?
Any advise will be much appreciated. Thank you!
string temp = "";
void check(string &str, int &i, int &flag)
{
int count = 0;
int reminder;
do
{
count++;
temp += str[i];
i++;
} while (str[i] != ' ');
i = i - temp.size();
reminder = count % 2;
if (reminder == 0)
flag = 1;
else
flag = 0;
}
void SplitEvenWord(string &str)
{
int i = 0;
int flag = 0;
for (i = 0; i < str.size(); i++)
{
check(str, i, flag);
if (flag == 1)
{
temp.insert(temp.size() / 2, " ");
str.replace(i, temp.size() - 1, temp);
}
}
}
There are two skills that are absolutely vital in software engineering (Well, more than two, but two for now): developing new functions in isolation, and testing things in the simplest possible way.
You say that the code fails if there is only one substring. You don't say how it fails (I should have mentioned clear error reports in the list) so I don't know whether to test your code with an even-length string which it ought to split ("ABCD" => "A B C D") or an odd-length string which it ought to leave alone ("ABC" => "ABC"). Before I try to code these up, I look at your first function:
void check(string &str, int &i, int &flag)
{
...
do
{
count++;
temp += str[i];
i++;
} while (str[i] != ' ');
...
}
Trouble already. The strings I have in mind do not contain any spaces, so the loop cannot terminate. This code will run past the end of the string into whatever happens to be in that memory space, which will cause undefined behavior. (If you don't know that term, it means that there's no telling what will happen, but if you're lucky the program will just crash.)
Fix that, try running that code on "ABC" and "ABCD" and "A" and "" and "ABC DEF", and get it working perfectly. Once it does, take a look at your other function. Don't test it with random typing, test it with short, clearly defined strings. Once it works perfectly, try longer, more complicated ones. If you find a string which causes it to fail, hold onto it! That string will lead you to a bug.
That should be enough to get you started.
I'm writing this as an answer because it was too long to fit as a comment.
I have a couple of suggestions that may help you to figure out what the problem is.
Separate "check" into at least two functions, one to split the string into individual words and check them and one to check the length of the string.
Test the "check" and "tokenize" functions by separately and see if they give you the expected answers. Work on them individually until they are correct.
Separate the formatting of the answers out of "SplitEvenWord" into a separate function.
"SplitEvenWord" should then be nothing more than calling the functions you created as a result of the steps above.
When I'm stuck, I always try to break the problem down into small bite sized pieces that I know I can get working. Eventually, the problem becomes assembling the already working pieces of the solution into a larger function that solves the original problem.

Vector out of range- C++

I'm working on a project that requires me to make a game of Hangman in c++. I have most of it working, but I'm stuck at printing out the part of the word guessed correctly each time after the user enters a guess. I've created a class to represent a game of hangman, and in this class are the methods that determine what to do for a guess. If a guess is found in any location in the randomly chosen word from a dictionary, I save that char to the same location in a vector called currentWord. currentWord is initialized in the constructor to be contain "_" for the length of the randomly chosen word(that way it is the same size as the word and I can just update it as the user types a guess). For example, if the word is "semicolonialism", and the user's first guess is 'i', I want to replace the '_' in the currentWord vector with the letter 'i'.
string tempWord = word;
for (int i = 0; i < tempWord.size(); i++) {
u_long location = tempWord.find(guess);
currentWord->at(location) = tempWord[location];
tempWord[location] = '_';
}
What I've tried to do is store the member variable "word" in a temporary variable called tempWord. Then I iterate from 0 to the length of tempword. I use tempWord.find(guess) to find the location in tempWord that is a match for the guess, store that into a variable called location, and then update the currentWord vector at that location to equal the tempWord at that location. Since this would only work for the first time the matching char is found, I then change tempWord[location] to '_', that way the next time through, location will be different. But by doing this I some times get the out of range error. If I comment out
tempWord[location] = '_';
then I don't see this error, but only the first occurrence is replaced. Even though I get this out of bounds error, I can see in the debugger that each occurrence is properly replaced in the currentWord vector. This leaves me very confused, so any help would be greatly appreciated! Thanks
EDIT
Thanks to rapptz suggestion to check if location is equal to std::string::npos, I finally have it working. Here's the updated code segment with that check in place:
string tempWord = word;
for (int i = 0; i < tempWord.size(); i++) {
u_long location = tempWord.find(guess);
if (location != std::string::npos) {
currentWord->at(location) = tempWord[location];
tempWord[location] = '_';
}
}
I really liked Tristan's suggestion too, and will do that tomorrow most likely. Once I do, I'll post the updated code as well in case someone else might find it useful. Thanks again!
Was going to post this as a comment but it's easier in a bigger text box! You can avoid both the tempWord copy and the for loop like this:
std::string::size_type location = 0, start_pos = 0; // int would be fine, tbh
while ( (location = word.find(guess, start_pos)) != std::string::npos) {
currentWord.at(location) = word[location];
start_pos = location;
}
My guess is that tempword.find(guess) starts from 1 to the lenght of word, not 0. Please share that function too.

How do I output an individual character when using char *[] = "something"

I've been playing with pointers to better understand them and I came across something I think I should be able to do, but can't sort out how. The code below works fine - I can output "a", "dog", "socks", and "pants" - but what if I wanted to just output the 'o' from "socks"? How would I do that?
char *mars[4] = { "a", "dog", "sock", "pants" };
for ( int counter = 0; counter < 4; counter++ )
{
cout << mars[ counter ];
}
Please forgive me if the question is answered somewhere - there are 30+ pages of C++ pointer related question, and I spent about 90 minutes looking through them, as well as reading various (very informative) articles, before deciding to ask.
mars[i][j] will print the j'th character of the i'th string.
So mars[2][1] is 'o'.
As has been pointed out before, strings are arrays. In fact, this concept is carried on the the std::string-class (which, by the way, is the preferred way of representing strings in C++), which implements all the requirements of an STL-Sequence. Furthermore it implements the array-subscript operator. That means the expression:
mars[i][j]
would also work if mars was declared as
std::vector< std::string > mars;
which is much more the C++ way of handling this. I realize you are doing this to learn about pointers, but I just thought I'd add this for your information. Also, when learning about pointers in C++, you should also learn about iterators, as they are generalizations of pointers.
cout << mars[2][1] ;
mars is an array of char * so to get the individual char you have to index into the array of char
mars[counter] is of type char *, pointing to a zero-terminated string of characters. So you could:
for ( int counter = 0; counter < 4; counter++ )
{
char * str = mars[ counter ];
size_t len = strlen(str);
if (len >= 2)
cout << str[1];
}
Since others have suggested easy way, please also find one round-about way of doing it ;)
char *myChar = &mars[ 1 ][0];
int nPosOfCharToLocate = 1;
myChar = myChar + nPosOfCharToLocate;
cout <<*myChar<<endl;

PopFront Delimma C++

Strange programming problems as of now..As you can see below i have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront( int &popFront )
{
//items[count-1].n = { 9,4,3,2,1,0 };
nPopFront = items[0].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
--count;
return true;
}
Its just my implementation of a cross between a queue and a stack..PopFront is a public method of the class object quack..The items is a private struct type 'item', it is within the quack.h. It has one member, 'int n'..But, that is irrelevent.
the comment in the code is the contents of my integer array, 'items'.
I am trying to Pop elements off the front of my array. WHat im thinking is that after i get the first item, i'll just incrememnt the frontPtr and transfer the item i got previously to the frontPtr i incremented!...
I cannot, for any reason, use a + or - shift by 1 or the use of stls, boosts, std's and the like..
Can someone help me with my homework assignment?
My suggestion are :
1). Put statement --count where it keeps object's state valid on exceptional condition.
2). clear your concepts of pointers which will help you a lot.
Generally, I would not recommend using an array if you want to pop items off the front. You would be much better off using a linked list, or some other structure which will allow you to remove items in O(1) time. It will be much easier to remove (pop) items this way.
As for your current code, I really can't comment without a better idea of what your class looks like. Please post the class definition at least so we can tell what all your variables are referring to, and what you're code is actually doing.
There are quite a few problems. But I believe your major one is this loop:
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
It looks to me like you are trying to shift all your items down. Since this is homework, I'm not going to give you the answer but I'll give you some hints to help debug this.
What you want to do is examine your items array at the beginning and end of the loop.
for (int temp; intFrontPtr < intBackPtr ;)
{
// whats does array look like here
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
// and what does array look like here
}
If you don't have experience with a debugger, add a function call that will dump your array.