1

I'm pretty unfamiliar with string manipulation in C++ and I can't seem to wrap my head around how to select characters in strings. Below is my program so far. Whenever I run it, however, the program crashes and an error showing "Thread 1: EXC_BAD..." shows up (I'm working on Xcode). For some reason, simply using input[0] works if I want to print the first character from the string, but doesn't when I do input[x] in a loop.

#include <iostream> #include <string> int num, characterCount; string currentChar, previousChar; int main() { cout << "How many lines of input? \n"; cin >> num; for (int x = 0; x < num; x++) { string input; cin >> input; previousChar = input[0]; currentChar = input[1]; characterCount = 0; int y = 0; while (currentChar != "") { y++; if (previousChar == currentChar) { characterCount++; } else if (previousChar != currentchar && currentChar != "") { cout << characterCount << " " << previousChar; characterCount = 0; } else if (currentChar == "") { cout << characterCount << " " << previousChar; } previousChar = currentChar; currentChar = input[y]; } } return 0; } 

Btw I know my code's weird, I'm a beginner in C++. If you have any helpful suggestions feel free to comment!

0

3 Answers 3

1
 previousChar = input[0]; currentChar = input[1]; 

If an empty string was entered, there is no input[0] and there is no input[1], so this becomes undefined behavior.

Your overall problem is checking, incorrectly, when the end of the string has been reached. The shown code attempts to extract a character at each position, place this character into a std::string of its own, and then compare it to an empty string.

This is not the right way to do that. This eventually results in undefined behavior, too, and a likely crash. std::strings have a size() method that give the number of characters in the string, so in your case:

input.size() 

gives the number of characters in the string. Which can be 0. Then, you can iterate over each character of the string, and then implement your logic.

Sign up to request clarification or add additional context in comments.

Comments

0

The reason you are getting the error is:

currentChar = input[y]; 

The problem with this line is that input[y] might be inaccessible, for instance your input is "Hello". With the way you wrote your code, y would eventually equals 5. However, you the last letter 'o' is input[4]. Because of that, when y=5, you get an error.

There are couple ways you could fix it. One has already mentioned using .size() to make sure, another one has mentioned using iterator:

for(auto iterator = input.begin();iterator!=input.end();++iterator)

However, what I want to mention is that you should be declaring your currentChar and previousChar as char type instead of string since they would always be single characters. Also, depends on the version of C++ and compiler you are using, if you are using C++11, input[5] on "Hello" is actually fine.

When you passed input[5] to a char currentChar type, currentChar gets a null character. So for you while loop, you could test while(currentChar). When currentChar gets the null character, the while loop would test false, and ends the loop.

Below is how I would change inside your for loop. Most of them stays the same, beside changing previousChar and currentChar into char type, and some condition checkings for them, with some minor changes to refine them.

#include <iostream> #include <string> int main() { int num; std::cout << "How many lines of input? \n"; std::cin >> num; for (int x = 0; x < num; x++) { std::string input; std::cin >> input; char previousChar = input[0]; int y = 1; char currentChar = input[y]; int characterCount = 1; while(currentChar) { y++; if (previousChar == currentChar) { characterCount++; } else { std::cout << characterCount << " " << previousChar << "\n"; characterCount = 1; } previousChar = currentChar; currentChar = input[y]; } std::cout << characterCount << " " << previousChar << "\n"; } } 

Also do note that it feels weird to use a while loop when it is iterating through a index number for me. So I would probably use a for loop instead of the while loop:

#include <iostream> #include <string> int main() { int num; std::cout << "How many lines of input? \n"; std::cin >> num; for (int x = 0; x < num; x++) { std::string input; std::cin >> input; char previousChar = input[0]; int y = 1; char currentChar = input[y]; int characterCount = 0; for(int y = 1; currentChar; y++) { if (previousChar == currentChar) { characterCount++; } else { std::cout << characterCount << " " << previousChar << "\n"; characterCount = 1; } previousChar = currentChar; currentChar = input[y]; } std::cout << characterCount << " " << previousChar << "\n"; } } 

And here is how you could do it with iterator:

#include <iostream> #include <string> int main() { int num; std::cout << "How many lines of input? \n"; std::cin >> num; for (int x = 0; x < num; x++) { std::string input; std::cin >> input; char previousChar, currentChar; previousChar = input[0]; int characterCount = 1; for(auto it = input.begin()+1; it != input.end();it++) { currentChar = *it; if (previousChar == currentChar) { characterCount++; } else { std::cout << characterCount << " " << previousChar << "\n"; characterCount = 1; } previousChar = currentChar; } std::cout << characterCount << " " << previousChar << "\n"; } } 

4 Comments

I've tried both the first and second solutions that you've shown, and neither actually get to cout << characterCount before the program ends. What could the problem be?
The code I had require c++ 11 or later. And it's possible you are using an older version of c++. You can refer to: apple.stackexchange.com/questions/350627/… to change your c++ version
actually, my version is c++ 17, which I think is the most recent version. Basically, after I enter the input in the program, it immediately ends. I've tried inserting cout << "trigger" in else {}, but it didn't print so I'm assuming that it doesn't even reach else {} before ending.
@Anthony I've updated my post, included the entire code. It should be working this time
0

From what I get by reading your code you are trying to print the number of duplicate characters. How I would go about doing this is as follows:

 #include <iostream> #include <string> int num, characterCount; int main() { std::cout << "How many lines of input? \n"; std::cin >> num; for (int x = 0; x < num; x++) { characterCount=0; std::string input; std::cin >> input; for(auto iterator = input.begin();iterator!=input.end();++iterator) { if(iterator == input.end()-1) std::cout <<"Duplicates: " << characterCount << " " <<"Character: "<< *iterator << "\n"; else { if(*iterator == *std::next(iterator,1)) characterCount++; else { std::cout <<"Duplicates: " << characterCount << " " <<"Character: "<< *iterator << "\n"; characterCount=0; } } } } return 0; } 

First of all, you weren't using the std namespace. You need to use std:: like I did below before every call from that particular namespace or you can just using namespace std at the top of the file after the include directives.

Second of all I ditched your algorithm using previous character and current character in favour of an approach using iterators.. A string is a standard c++ container from the standard template library so we can use iterators to go over it (or a standard for loop if you so desire).

The code prints duplicates for each character in the string, much as you wanted to do I think.

1 Comment

Oh, I forgot to add using namespace std. In this program, I'm trying to count and print the number of different characters in a string, and then count how many of each character there are. I guess I should've made that clear.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.