Identify a specific word in a C++ String, is there a function ready for that? Or just in the nail itself?

Asked

Viewed 95 times

0

Hello,

I’m getting a series of strings(lines) from a . txt file and putting them into a vector. But there’s a problem, strings come with an unwanted start, example:

  Depende: lsb-release
  Depende: libatk1.0-0
  Depende: libc6
  Depende: libcairo-gobject2
  Depende: libcairo2
  Depende: libdbus-1-3
  Depende: libdbus-glib-1-2
  Depende: libfontconfig1
  Depende: libfreetype6
  Depende: libgcc1
  Depende: libgdk-pixbuf2.0-0
  Depende: libglib2.0-0
  Depende: libgtk-3-0
  Depende: libpango-1.0-0
  Depende: libpangocairo-1.0-0
  Depende: libstartup-notification0
  Depende: libstdc++6
  Depende: libx11-6

I would like to remove the beginning of each of them, the "Depends". Is there a function ready for this or will I have to do it in the nail? Each line of this I’ve put inside a vector.

3 answers

1

There are some ways to do this, one of them being with std::string::find_last_of and std::string::substr: finding the position of space after Depende: and creating a substring that starts from that position.

#include <string>
#include <cassert>

int main()
{
    std::string s = " Depende: lsb-release";
    const size_t p = s.find_last_of(' ');
    std::string pacote = s.substr(p + 1);
    assert(pacote == "lsb-release");
}

Another possible way is to use std::string::substr directly, passing the number of characters to be skipped, in case you know that the string will always start with " Depende: ".

Yet another way is to use std::string::replace, to locally remove this prefix from the string:

#include <string>
#include <cassert>

int main()
{
    std::string s = " Depende: lsb-release";
    const size_t p = s.find_last_of(' ');
    s.replace(0, p + 1, ""); //< Substitui " Depende: " com "".
    assert(s == "lsb-release");
}

There is also the solution with regex (as seen in Reply by @Marcosbanik), but I avoid using it because of its controversy.

  • THANK YOU!! VERY GOOD TOO!!!!!

0

regex_replace may be what you seek.

#include <iostream>
#include <regex>
#include <string>

int main() {
  std::string line1{"Depende: lsb-release"};
  std::string line2{"Independe: lsb-release"};
  std::regex exp("^Depende: ");
  std::cout << std::regex_replace(line1, exp, "") << "\n";
  std::cout << std::regex_replace(line2, exp, "") << "\n";
}

0

The answers were great, maybe I redo my code. I ended up finishing it on the nail. But I liked knowing that I can "automate" this. I solved it this way:

#ifndef PACOTE_H
#define PACOTE_H
#include <vector>
#include <fstream>
#include <string>

class Pacote
{
    public:
        /*Metodo que retorna o nome do pacote definido pelo usuário*/
        std::string GetnomeDoPacote(){
        return nomeDoPacote;}

        /*Metodo que define o nome do pacote a ser trabalhado*/
        void SetnomeDoPacote(std::string variavelNomeDoPacote){
        nomeDoPacote = variavelNomeDoPacote;}

        /*Metodo que retorna as dependencias do pacote*/
        std::vector<std::string> GetdependenciasDoPacote(){
        return dependenciasDoPacote;}

        /*Metodo que extrai as dependencias do pacote de um arquivo .txt linha a linha, para que elas sejam trabalhadas*/
        void SetdependenciasDoPacote(std::string TXT){
          std::string linha;
          std::ifstream dependenciasTXT (TXT);
          if (dependenciasTXT.is_open())
          {
            while ( getline(dependenciasTXT,linha) )
            {
              dependenciasDoPacote.push_back(linha);
            }
            /*O primeiro e o último elemento do arquivo .txt não nos enteressa, pois eles não contem o nome de
            nenhuma dependencia a ser baixada*/
            dependenciasDoPacote.erase(dependenciasDoPacote.begin());
            dependenciasDoPacote.pop_back();
            /*Para cada elemento adquirido através do comando 'apt-cache depends', temos as classificaçoes "Depende", "Recomendado" e "Sugere".
            Precisamos remover essas strings do vector que armazenará essas dependências, logo, o esquema abaixo busca pelo primeiro elemento dessas
            strings, afim de identifica-las e removêlas atráves do comando erase.*/
            for(int linha = 0; linha < dependenciasDoPacote.size(); linha++){
                for(int elementoDaLinha = 2; elementoDaLinha < sizeof(dependenciasDoPacote[linha]); elementoDaLinha++){
                    if(dependenciasDoPacote[linha][elementoDaLinha] == 'D'){
                        dependenciasDoPacote[linha].erase(dependenciasDoPacote[linha].begin(), dependenciasDoPacote[linha].begin()+10);
                    }
                    else
                    if(dependenciasDoPacote[linha][elementoDaLinha] == 'R'){
                        dependenciasDoPacote[linha].erase(dependenciasDoPacote[linha].begin(), dependenciasDoPacote[linha].begin()+12);
                    }
                    else
                    if(dependenciasDoPacote[linha][elementoDaLinha] == 'S'){
                        dependenciasDoPacote[linha].erase(dependenciasDoPacote[linha].begin(), dependenciasDoPacote[linha].begin()+9);
                    }
                }
            }
            dependenciasTXT.close();
          }

          else{
            dependenciasDoPacote.push_back("Não foi possível encontrar o arquivo de dependências! :(");
            }
        }

        /*Metodo que retorna o nome do repositório PPA do pacote, definido pelo usuario*/
        std::string GetrepositorioPPADoPacote(){
        return repositorioPPADoPacote;}

        /*Metodo que define o nome do repositório PPA a ser trabalhado*/
        void SetrepositorioPPADoPacote(std::string nomeDoRepositorioPPA){
        repositorioPPADoPacote = nomeDoRepositorioPPA; }

    private:
        std::string nomeDoPacote;
        std::vector<std::string> dependenciasDoPacote;
        std::string repositorioPPADoPacote;
};

#endif PACOTE_H

I used the Rase and Begin method. Okay, it wasn’t exactly on the nail, but it was almost on the nail. dependencesDoPackage[line]. Rase(dependencesDoPackage[line]. Begin(), dependencesDoPackage[line]. Begin()+9);

With Rase I define that I want to erase, and with Begin I say that I want to erase by the front. I’m working with a vector. the vector line 0 has a certain amount of elements, and if I say 'dependencesDoPackage[line]. Begin(), I refer to the first element(element 0). In the above passage, I say I want to delete from element 0 to element 9.

dependencesDoPackage[line]. Rase(dependencesDoPackage[line]. Begin() /of element 0/, dependencesDoPackage[line]. Begin()+9 /to element 9/);

This works because the . txt file being worked on follows a pattern. It always starts at the [line][2] element of the vector. And it always starts either with Recommended, or with Depends, or with Suggests. So, I know, through ifs and elses what I’m deleting or not. If recommended, starting with the element [line][2] by the letter 'R', I delete until such element, if it is Suggest, starting with the letter’S', I delete until such element.... Anyway. Please point out errors or bad practices in my code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.