For my homework, part of what I need to do is take a phrase from the user, and from there take only the letters in the phrase, ignoring numbers, spaces, and special characters. Once I find letters in the string, I need to store them into a separate variable. However, I can't get that variable to store anything outside of the if statement that looks for letters.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line, temp;
cout << "Enter phrase to check: ";
getline(cin, line);
for(int i = 0; i < line.size(); i++)
{
if((line[i] > 64 && line[i] < 91) || (line[i] > 96 && line[i] < 123))
{
temp[i] = line[i];
}
}
cout << temp;
return 0;
}
When I run the program, temp outputs nothing. But I know the if statement is correctly finding letters, from making it print line[i] inside the if statement.
your temp variable is an empty string. temp[x] is telling the compiler to change the x-th character of that string(which doesn't make any sense, as the string doesn't have any characters!). You're lucky(or unlucky) that you aren't getting any Segmentation faults(crashes).
Just use the += operator:
temp += line[i];
Try
temp.push_back(line[i]);
It will work.
The way you're currently doing it (temp[i] = line[i];) means that each non special character in line will be placed at the same index in temp. This should usually fail since temp (a string) does not resize on indexing.
For changing the size of a string, there exists a function called string::push_back as detailed here.
Instead of indexing using temp[i], you would instead use temp.push_back(line[i]);
This function allows the string to resize itself to accommodate the new char if need be and won't throw a segmentation fault.
NB: std::string::push_back is designed to append a single char to a string. There exist multiple other ways of doing this, including Nikita Demodov's answer which shows the use of the += operator which is much more lenient and will allow appending of other strings etc. push_back is most common to the std::vector where it is used to append single items to the list.
Related
I've tried to separate A-Z character in a given string using c++ but the separated string is not printing in the output but if I shift the "cout" statement inside the for loop it printing the characters. I don't know why its happen. please let me know if I've done any mistake.
my code
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t; //number of test cases
while(t--)
{
string s,a,n;
int j=0,k=0;
char temp;
cin>>s; //getting string
for(int i=0; i<s.length(); i++)
{
if(s[i]>=65 && s[i]<=90) //checking for alphabets
{
a[j]=s[i];
j++;
cout<<a[j-1]<<endl;
}
else
{
n[k]=s[i];
k++;
cout<<n[k-1]<<endl;
}
}
cout<<endl<<a<<endl<<n; //this line is not printing
}
}
String a is empty after initialization (i.e. it has length 0). So you can't access/write any character using a[j], because this writes beyound the string's current bounds and yields undefined behaviour.
use...
a.push_back(s[i]);
to append a character at the end of the string.
Since a is empty at the beginning and, as other answer says, you are writing beyond the string's current bounds, you can resize it to the size of s by doing the following:
a.resize(s.size());
and, once you are done with the work, reduce its capacity to fit the actual size:
a.shrink_to_fit();
This way you won't have memory reallocations that you might have when using std::string::push_back.
Also, you can use isupper() function in your first if condition.
But first you have to initialize s[i] into char variable at first for loop and add #include<cctype> library. Like this:
char c = s[i];
if(isupper(c)){code}
Not a homework question.
I am self learning.
I have to remove consecutive characters in a string by recursion. However the program I made is not working for inputs containing duplicates. It is goining in infinite recursion and hence gives segmentation fault. However it is working for inputs which doesn't have consecutive duplicates in them. I have tried debugging in Eclipse Ide but things get weird when I debug. (I know how to debug) but I can't figure out the things are different when I debug and when I run. I will give you example after my code.
#include <iostream>
#include <cstring>
using namespace std;
void removeConsecutiveDuplicates(char *input) {
int l = strlen(input);
if(l == 0) {
return;
}
if(input[0] != input[1]) {
removeConsecutiveDuplicates(input+1);
return;
}
int i = 1;
for(; input[i] != '\0'; ++i) {
input[i-1] = input[i];
}
input[i] = '\0';
removeConsecutiveDuplicates(input);
}
int main(void) {
char ch[1000];
cin >> ch;
cout<<"The String Before Removing Duplicates : "<<ch<<endl;
removeConsecutiveDuplicates(ch);
cout<<"The String After Removing Duplicates : "<<ch<<endl;
return 0;
}
When I am debugging this code I and seeing the variable l value it is 16. This doesn't happen while running. What I am missing here?
This line :
input[i] = '\0';
doesn't do anything (input[i] already has that value, because that was the end condition for the loop). You then call the removeConsecutiveDuplicates function recursively, but the length of the string is still the same, so you'll keep making recursive calls until a stack overflow happens.
Instead, you need to make the string length smaller :
input[i - 1] = '\0';
to avoid this infinite recursion.
To pass your self-assigned homework problem :), explain why the following line never has any effect in your code:
input[i] = '\0';
In your function, change this:
input[i] = '\0';
to this:
input[i-1] = '\0';
since you have chopped away a character, thus you should decrease the size of your string.
Without that, you wouldn't reduce the size, thus looping over and over again the same size, without it changing, would result in an infinite loop (since the size wouldn't change).
I suggest you use an std::string next time, since this is C++.
I have an input string which I will use to build an output string. The output string is much the same as the input string but has some slight changes along the way, depending on if we hit a certain characters in the input. The code looks like this
outputTree(std::ostream& o, const char* input) {
size_t len = strlen(input);
int indent = 0;
string output;
for(size_t i = 0; i < input_len; i++) {
if(input[i] == '(') {
indent++;
output.append(1,'\n');
for(int j = 0; j < indent; j++) {
output.append(" ");
}
}
if(input[i] == ')') {
output.append(1,'\n');
for(int j = 0; j < indent; j++) {
output.append(" ");
}
indent--;
}
output.append(1,input[i]);
}
o << output << endl;
}
While this works, doing it character by character is pretty slow. Can anyone recommend some better approaches to this (pref with standard features, ie no boost)?
I am not sure what "pretty slow" means and how much improvement you expect. The algorithm you have is an efficient O(N) algorithm. The only thing you can do is trying to optimise individual operations, but then again I am not sure what kind of optimisations is the compiler doing.
One thing you could do is get rid of the inner loops that write the indentation string as many times is needed by the level of indentation (your indent variable). So instead of writing a newline and then execute the for loop, you can perform just one append that has the newline concatenated with the right amount of indentation. If you can set a limit to the depth of your indentation (say 10 levels deep) you can then create an array that has all 10 different indentation strings (all strings starting with a newline).
Another thing you can try is to use std::string::find to find the occurrences of '(' and ')' and do string copies up to these markers, instead of copying character by character.
Finally, note that your code might not behave as you want it, if the input is not as expected. Notice what will happen if you first encounter a ')' without having a corresponding '('.
So I want to create 1000 words with a length of 5 random characters. In my main I have word[1000] but when I try to run this code, it gives me an error saying "Expression:string subscript out of range". I'm not sure why it does that because I thought string arrays were 2 dimensional? If anyone could tell me why my code is wrong I'd appreciate it. Thanks.
void createText(string w[], int seed) {
char ch;
srand(seed);
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 5; j++) {
ch = ('A' + rand() % 26);
w[i][j] = ch;
}
}
for(int i = 0; i < 1000; i++) {
cout << w[i];
}
cout << endl;
}
I suppose that the array w does not have 1000 elements, also remember that here you will get a copy of string w[]. Better would be passing a pointer to w (string* w), then You will have very clearly what is wrong. remember also that cout writes the string out untill it reaches a '\0' character, this also might be the cause. Quick session with gdb will help:
gdb program
...
run
bt full
should pinpoint Your problem. if it's some kind of IDE, learn how to debug in it. Valgrind or some other memcheck like visual leak detector or luke stackwalker will also show you some tips about bad initialization or unmentioned memory leaks.
If an array is bidimensional, you can't print its values like w[i]. You must print always keeping in mind that the array is bidimensional, which means that the output must be done like cout << w[i][j];
In addition, you're passing an array of strings as an argument, and what you're doing is add characters to every single position, which means that you won't actually have nothing but 1000 characters inserted into that string (because you actually added "one-char" strings), so you'll only put 200 words with a length of 5 characters each one. Insert strings directly, and you'll get your 1000 words, but first find a way to build strings with random characters.
Something like:
for(conditions){
for(conditions){
build a word
}
array[x][y] = string
}
I guess it is similar to what you intended to do
I want to be able to to take the user input and assign the given letter a value. I think I got that part down, now the problem is returning the value.
#include <iostream>
#include <string>
using namespace std;
int ch2n(string word);
int main()
{
string inputWord;
cout << "Type Word: ";
cin >> inputWord;
cout << ch2n(inputWord);
}
int ch2n(string word)
{
int total = 0;
for(int i = 0;i != word.size(); i++)
{
if(word.find(i) == 'a' || word.find(i) == 'A')
{
total += 1;
}
}
return total;
}
when I declare the total to 0, the return is always 0, but when I don't declare it, I get a return value of 229.... etc random number.
I think word.find(i) is probably not what you want to call there. To access a specific character within the string, use square brackets, i.e.: word[i] instead of word.find(i).
If you don't initialize it (set its value), using it is undefined behaviour and can return any random value - including 0
types without constructor, like int will just allocate space and have an undefinedd value, generally based on whatever happens to be in that location from prior use.
word.find does not do what you think it does, it is searching for i in word
You want to just use word[] :
if(word[i] == 'a' || word[i] == 'A')
Also, you might want to put std::endl at the end of your cout lines
The reason your result is random if you don't declare it to be 0 is because c++, and c for that matter, do not initialize data. If you declare a variable, like total, the initial value is whatever happens to be in that place in memory. It could really be anything. Always initialize the value of a variable.
I think the reason you're not returning anything meaningful is because you're using find wrong. std::string::find does not return a boolean, if returns a position. Therefore, you want to check if against a string position which says "The character does not exist in this string." That is std::string::npos. So, you will want:
if(word.find('a') != string::npos || word.find('A') != string::npos){
total += 1;
}