nSv23
nSv23

Reputation: 439

How to delete characters in vector of strings?

I am writing a code where I read a subtitle file and remove the text in () including the brackets themselves, that is subtitles for hearing impaired which have background noise in ().

The example:
13
00:01:08,535 --> 00:01:10,127 // remove this
(PIANO PLAYING) // remove this

125
00:07:09,162 --> 00:07:12,393
BOTH: (SINGING WITH RADIO) Teach // remove only the text in parenthesis, including ()
them well and let them lead the way

The code is here:

#include<iostream>
#include<fstream>
#include<string>
#include<vector>

using namespace std;

void subRem();

int main() {

    subRem();

    system("PAUSE");
}

void subRem() {

    ofstream out;
    ifstream in;

    out.open("whip it2.srt");
    if (out.fail()) {
        perror("whip it2.srt");
    }

    in.open("whip it.srt");
    if (out.fail()) {
        perror("whip it.srt");
    }

    vector<string> input;
    string inc;

    while (getline(in, inc)) {
        input.push_back(inc);
    }
    vector<int> len;
    for (int i = 0; i < input.size(); i++) {
        len.push_back(input[i].size());
    }

    for (int i = 0; i < input.size(); i++) {
        for (int j = 0; j < len[i]; j++) {
            if (input[i][j] == '(') {
                for (int k = j; k < len[i]; k++) {
                    j = k;
                    if (input[i][k] == ')') {
                        if (k == (len[i] - 1)) {
                            input[i - 1] = "";
                        }
                        input[i][k] = '\0';
                        break;
                    }
                    input[i][k] = '\0';
                }
            }
        }
    }

    for (int k = 0; k < input.size(); k++) {
        out << input[k] << endl;
    }
}

I want to delete the characters in parenthesis, so I am using:

input[i][k] = '\0';

The problem is the characters are removed but they are replaced by whitespace, for example:

(SHOUTING) with her?

I get:

___________with her?

(____ are whitespaces because I couldn't make them appear)

There is the white space. If it was string, I could do:

input[i][k] = "";

but with characters I get the error when I do:

input[i][k] = '';

quoted string should contain at least one character

I plan to improve the code further by renaming the line numbers and deleting extra newlines, but I want to create like an app where I can drag and drop the subtitle file and click run, to get the modified subtitle file. What do I need to know to create the GUI? Do I need to learn Qt or some other libraries?

Upvotes: 0

Views: 749

Answers (4)

Marko Tunjic
Marko Tunjic

Reputation: 1879

#include <iostream>
#include <regex>

int main() {

    std::string text("this text (remove this) and (remove this) end.");

    // First Method: with regular expression
    std::regex expr("\\(.*?\\)");
    std::cout << std::regex_replace (text, expr, "");

    // Second Method: with stl
    auto begin = text.find_first_of("(");
    auto end = text.find_last_of(")") + 1;
    if (std::string::npos != begin && std::string::npos != end && begin <= end)
        text.erase(begin, end-begin);

    // Optional
    std::cout << text << std::endl;

}

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490108

Since you're basically copying characters from one file to another, I'd just keep track of whether you're in a subtitle as you copy, and if so, don't copy characters until you encounter a close parenthesis again.

#include <string>
#include <iostream>
#include <sstream>

int main() {
    std::istringstream in{
R"(13
00:01:08,535 --> 00:01:10,127
(PIANO PLAYING)

125
00:07:09,162 --> 00:07:12,393
BOTH: (SINGING WITH RADIO) Teach
them well and let them lead the way)"   
};

    bool in_subtitle = false;

    std::string temp;
    while (std::getline(in, temp)) {
        unsigned line_len = 0;
        for (char ch : temp) {
            switch (ch) {
            case '(': in_subtitle = true; break;
            case ')': in_subtitle = false; break;
            default: 
                if (!in_subtitle) {
                    std::cout << ch;
                    ++line_len;
                }
                break;
            }
        }
        if (line_len != 0) std::cout << "\n";
    }
}

Upvotes: 0

Andr&#233; Fratelli
Andr&#233; Fratelli

Reputation: 6068

Try using substr. This method gives you a substring between two given positions. Although this solves the problem for your second problem, it leaves empty subtitles for strings on the first case. I would recommend checking for an empty result and removing the string at all.

Upvotes: 0

MSalters
MSalters

Reputation: 179779

std:;string can contain \0 without problems, it's not the end-of-string character inside a std::string. MikeCAT's suggestion is the correct answer: use std::string::erase.

(Please don't ask multiple questions at once, but yes Qt is a reasonable way to create GUI's)

Upvotes: 3

Related Questions