Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Spri

Segmentation fault sem motivo aparente

Recommended Posts

Olá pessoal, sou novo no fórum, e também na linguagem C++. Estou com um projeto pessoal de fazer uma calcuradora básica, e nele me deparei com esse problema:

 

Criei a função pegasubexp, para isolar uma conta e calculá-la. Ela retorna um vetor de strings, na primeira casa retorna a substring retirada de expr (expreção, o valor entrado pelo usuário), e na segunda retorna em qual casa o operador da conta matemática está nessa substring.

 

O problema, é que ao executar esse código, fora do loop while:

vector<string> calculo = pegasubexp(1,expr);
cout << spi(calculo[1]); //spi transforma string para int

O código funciona como o esperado, mas assim:

    vector<string> calculo;
    size_t qual;
    float resultado, c1, c2;
    int lixo;
///calculo da divisão:
    while(cemstr('/',operandos) == true)/*cemstr detecta se há o caractere na string*/{
        qual = operandos.find('/');//operandos é uma string com todos os operandos da expreção matemática
        calculo = pegasubexp(qual,expr);
        c1 = spi(calculo[0].substr(0,spi(calculo[1] - 1)));//em 9/3 c1 é 9
        c2 = spi(calculo[0].substr(spi(calculo[1]) + 1,calculo[0].size()));//em 9/3 c2 é 3
        resultado = c1 / c2;//calculo da divisão
        expr.replace(expr.find(calculo[0]),calculo[0].size(),ips(resultado));//substitui em expr a conta pelo resultado // ips é int para string
        operandos.erase(qual,1);//remove o operando da lista de operandos
    }
    cout << expr;

Ocorre esse erro de Segmentation fault, pelo que testei, na parte > spi(calculo[1]) - 1) < da variável c1. O código completo está aqui:

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

using namespace std;
///string para int
int spi(string str){
    istringstream ss(str);
    int n;
    ss >> n;
    return n;
}
///int para string
string ips(int n){
    ostringstream ss;
    ss << n;
    return ss.str();
}
///tnum = testa se char é número
bool tnum (char crc){
    crc = crc - 48;
    if(crc >= 0 && crc <= 9){
        return true;
    } else {
        return false;
    }
}

///eoprando = testa se é operando
bool eoprando (char crc){
    if (crc == '+' || crc == '-' || crc == '*' || crc == '/'){
        return true;
    } else {
        return false;
    }
}
//pega a posição verdadeira do operando, a posição dele em expr
int posop(int pos, const string& str){
    unsigned int i = 0;
    for (unsigned int crc, tamanho = str.size(); pos > 0; i++){
        crc = str.at(i);
        if (eoprando(crc) == true){
            pos--;
        } else if (i == tamanho - 1){
            i = 0;
            break;
        }
    }
    return i;
}
int cemstr(char alvo, const string& str){
    bool sim = false;
    for(int i = 0, tamanho = str.size(); i < tamanho; i++){
         if (str.at(i) == alvo){
            sim = true;
            break;
         }
    }
    return sim;
}
vector<string> pegasubexp(int pos, string& str){
    short int aopos = posop(pos - 1, str);
    short int mopos = posop(pos, str);
    short int popos = posop(pos + 1, str);
if(mopos == 0){
        vector<string> saida(1);
        saida[0] = "e";
        return saida;
} else {
    if (popos == 0){
        popos = str.size() + 1;
    }
    vector<string> saida(2);
    saida[0] = str.substr(aopos, popos - 1);
    saida[1] = ips(mopos - aopos);
    return saida;
}
}
int main(){
    cout << "Insira a exprecao matematica a ser calculada:   ";
    string expr;
    cin >> expr;
    ///etmh >> tamanho efetivo
    const int etmh = expr.size();
    ///encontrar caractere inválido
    bool sucesso = true;
    unsigned short int noprand = 0;
    string operandos;
    for (unsigned char i = 0, crc, acrc = 0, pcrc/**acrc = caractere anterior pcrc = próximo crc**/; i < etmh ; i++){
        if (i > 0){acrc = expr[i - 1];}
        crc = expr.at(i);
        if (i < etmh - 1){
            pcrc = expr[i + 1];
        }else{pcrc = 0;}
        ///testes de regularidade
        if (eoprando(crc) == true){
            noprand++;
            operandos += crc;
            if(tnum(acrc) == true && tnum(pcrc) == true){
                continue;
            } else {
                sucesso = false;
                break;
            }
        } else if (tnum(crc) == true) {
            continue;
        } else {
            sucesso = false;
            break;
        }
    }
if (sucesso == false || noprand == 0){
    cout << "Erro (1): Exprecao invalida inserida.\n";
    return 1;
} else {
    vector<string> calculo;
    size_t qual;
    float resultado, c1, c2;
///calculo da divisão:
    while(cemstr('/',operandos) == true){
        qual = operandos.find('/');
        calculo = pegasubexp(qual,expr);
        c1 = spi(calculo[0].substr(0,spi(calculo[1]) - 1));
        c2 = spi(calculo[0].substr(spi(calculo[1]) + 1,calculo[0].size()));
        resultado = c1 / c2;
        expr.replace(expr.find(calculo[0]),calculo[0].size(),ips(resultado));
        operandos.erase(qual,1);
    }
    cout << expr;
    return 0;
}
}

Tive que criar essas funções de conversão de str pra int e vice-versa, porque o MingWin não possui essas funções da linguagem c++. Mas creio que o problema não esteja aí.

Compartilhar este post


Link para o post
Compartilhar em outros sites

1- Se vc precisa colocar comentário tipo "///string para int" é porque os nomes dos seus métodos são ruins.

2- "expressão"

3- "crc, acrc = 0, pcrc, etmh" -> nomes de variáveis que não dizem nada a respeito delas.

4- O que esse negócio faz?

 

if (i > 0){acrc = expr[i - 1];}
        crc = expr.at(i);
        if (i < etmh - 1){
            pcrc = expr[i + 1];
        }else{pcrc = 0;}

 

 

http://invision-web.net/web/computing-arithmetic-expressions-given-as-strings-c-solution/

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.