Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a new string without spaces from another string using a loop

Tags:

c++

string

loops

I started off trying to write a function that would delete spaces from a string, but now that I've looked at a host of other peoples' solutions to that problem, I'm more just trying to understand exactly what went wrong in my code/why the std::cout << t << std::endl; at the end doesn't output anything.

When I included std::cout << t[count]; during the loop (the statement that is commented out below) it correctly would output to the console: hereissometext without spaces. When I have std::cout << t[0] << std::endl; at the end, it correctly outputs h, t[1] as e, t[2] as r, and so on. However, when I try to output t at the end, it outputs blank space, and t.size() outputs 0.

I am fairly new to coding so forgive me if this is a completely obvious question.

    std::string s = "here is some text";
    std::string t = "";
    int count = 0;

    for (int i = 0; i < s.size(); i++) {
        if (std::isalpha(s[i])) {
            t[count]+=s[i];
            // std::cout << t[count];
            count++;
        }
    }

    std::cout << t << std::endl;
like image 277
g_h Avatar asked Jul 22 '19 06:07

g_h


3 Answers

You have undefined behavior in your loop, as you insert into a std::string using its operator[] without making sure it has the right size. You can instead use

t.push_back(s[i]);

which not only inserts a char, but also makes sure the internal buffer is (re-)allocated when it's too small for the new string.

Note further that you don't really need the count variable. std::string always keeps track of its length, so t.size() will always yield the value of your current count (once you fix the UB of course).

As an aside, copying the parts of a sequence that match a certain criterion is a common task, and there exists a specific library template that does exactly this and frees you from a hand-crafted loop:

#include <algorithm>

std::copy_if(s.cbegin(), s.cend(), std::back_inserter(t),
     [](char c){ return std::isalpha(c); });

Finally, also note the comment by @MatthieurFoltzer on the behavior of std::isalpha, which might be worth taking into account.

like image 95
lubgr Avatar answered Sep 22 '22 19:09

lubgr


t[count]+=s[i];

This doesn't work like that. With this you can change existing characters of the string. But since your string is empty, that causes undefined behavior. To append to the string, change that line to this instead:

t += s[i];

And it'll print the desired output of hereissometext. You can find the documentation of the += operator for strings here.

like image 22
Blaze Avatar answered Sep 20 '22 19:09

Blaze


I suggest to not use a hand crafted loop. You can use std::copy_if in combination with a lambda expression to formulate your condition. This will be more stable than your implementation (what happens if the length of your string s exceeds the capacity of an int?). I think it also enhances the readability.

#include <algorithm>
#include <iostream>
#include <string>

int main() {
    std::string s = "here is some text";
    std::string t = "";
    auto comp = [&](const char c) { return std::isalpha(c); };
    std::copy_if(s.begin(), s.end(), std::back_inserter(t), comp);

    std::cout << t << std::endl;
}
like image 36
schorsch312 Avatar answered Sep 22 '22 19:09

schorsch312