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

0

Hello,

I'm getting a series of strings from a .txt file and putting them in a vector. But have a problem, the 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'd like to remove the beginning of each of them, the "Depends:". Is there any function ready for this or am I going to have to do it myself? Each line I've already placed inside a vector.

    
asked by anonymous 08.04.2018 / 14:31

3 answers

1

There are a few ways you can do this, one of them being std::string::find_last_of and < a href="http://en.cppreference.com/w/cpp/string/basic_string/substr"> std::string::substr ": Finding the position of the space after Depende: and creating a substring that starts from 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 if you know the string always starts 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 @MarcosBanik response ), but I avoid using it because of their controversy.

    
08.04.2018 / 15:44
0

regex_replace might be what you are looking for.

#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";
}
    
08.04.2018 / 15:36
0

The answers were great, maybe I'd redo my code. I ended up finishing it on the same nail. But I enjoyed knowing that I can "automate" this. I solved it as follows:

#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 erase method and begin. Okay, it was not exactly on the nail, but it was almost on the nail. (line dependencies) [line] .erase (package dependencies [line] .begin (), packet dependencies [line] .begin () + 9);

With the erase I define that I want to delete, and with the begin I say that I want to erase from the front. I am working with a vector. line 0 of the vector has a certain amount of elements, and if I say'Position dependencies [line] .begin (), I'm referring to the first element (element 0). In the above excerpt, I say that I want to delete element 0 through element 9.

DependenciesOfPacote [row] .erase (dependenciesDoPacote [line] .begin () / of element 0 /, dependenciesDoPacote [row] .begin () + 9 / to element 9 /);

This works because the .txt file being worked follows a pattern. It always begins in the vector element [line] [2]. And 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 it is recommended, which starts with the element [line] [2] by the letter 'R', I delete that element, if it suggests, which starts with the letter 'S', I delete that element .... Anyway. Please point out errors or bad practices in my code.

    
08.04.2018 / 16:11