web-dev-qa-db-fra.com

vecteur en fonction - comment faire retour

J'ai une fonction qui devrait lire un fichier ligne par ligne, la lecture s'arrête lorsqu'une ligne ne commence pas par '>' ou ''. Il devrait stocker les lignes dans le vecteur et le renvoyer.
Voici le code:

    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <fstream>
    #include <vector>

    using namespace std;

    string getseq(char * db_file) // gets sequences from file
            {
                string seqdb;
                vector<string> seqs;
                ifstream ifs(db_file);
                string line;

                //vector<char> seqs[size/3];

                while(ifs.good())
                {
                    getline(ifs, seqdb);
                    if (seqdb[0] != '>' & seqdb[0]!=' ')
                    {
                        seqs.Push_back(seqdb);
                    }
                }

            ifs.close();
            //return seqs;

            //return seqs;
            }

    int main(int argc, char * argv[1])
    {
        cout << "Sequences: \n" << getseq(argv[1]) << endl;
        return 0;
    }

Le compilateur (g ++) renvoie:

    fasta_parser.cpp: In function ‘std::string getseq(char*)’:
    fasta_parser.cpp:32: error: conversion from ‘std::vector<std::basic_string<char, `std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >’ to non-scalar type ‘std::string’ requested`

Quelqu'un a une idée?

Edit: Comme Skurmendel le demande, j'ajoute du code entier en raison d'une violation de la sécurité de la mémoire après

exécution du code compilé:

#include <cstdlib>
#include <iostream>
#include <string>
#include <stdio.h>
#include <fstream>
#include <vector>

using namespace std;

vector<string> getseq(char * db_file) // pobiera sekwencje z pliku
        {
            string seqdb;
            vector<string> seqs;
            ifstream ifs(db_file);
            string line;

            //vector<char> seqs[size/3];

            while(ifs.good())
            {
                getline(ifs, seqdb);
                if (seqdb[0] != '>' & seqdb[0]!=' ')
                {
                    seqs.Push_back(seqdb);
                }
            }

        ifs.close();
        return seqs;
        }

int main(int argc, char * argv[1])
{
    vector<string> seqs;   // Holds our strings.
    getseq(argv[1]); // We don't return anything.

    // This is just a matter of taste, we create an alias for the vector<string> iterator type.
    typedef vector<string>::iterator string_iter;

    // Print prelude.
    cout << "Sekwencje: \n";

    // Loop till we hit the end of the vector.
    for (string_iter i = seqs.begin(); i != seqs.end(); i++)
    {
        cout << *i << " "; // Do processing, add endlines, commas here etc.
    }

    cout << endl;
}
13
Mateusz Korycinski

Si je vous ai compris, votre getseq () devrait renvoyer un vecteur de chaînes. Par conséquent, vous devriez changer

string getseq(char * db_file)

à

vector<string> getseq(char * db_file)

Et si vous voulez l'imprimer sur main (), vous devez le faire en boucle.

int main() {
     vector<string> str_vec = getseq(argv[1]);
     for(vector<string>::iterator it = str_vec.begin(); it != str_vec.end(); it++) {
         cout << *it << endl;
     }
}
11
vtorhonen

Votre fonction getseq est déclarée renvoyer std::string Mais vous essayez de renvoyer une valeur d'un autre type - std::vector - donc vous avez cette erreur du compilateur. Vous devez renvoyer une variable de type std::string (Créée en concaténant des éléments de votre vecteur).

Votre fonction pourrait ressembler à ceci:

string getseq(char* db_file)
{
   string strSeqs;
   vector<string> seqs;

   ... // fill the vector; manipulate with ifstream

   for(vector<string>::iterator it = seqs.begin(); it != seqs.end(); ++it) 
   {
      strSeqs += *it;
   }

   return strSeqs; 
}

Remarque: la chaîne que vous renvoyez d'une fonction peut être un objet assez volumineux et le renvoyer par valeur peut être coûteux car ce qui est réellement retourné dans ce cas est une copie de cet objet (construite en appelant le constructeur de copie). Ce serait plus efficace si votre chaîne est déclarée comme paramètre out que vous venez de remplir dans la fonction:

void getseq(char* db_file, string& strSeqs);

string strSeqs;
getseq(argv[1], strSeqs);
cout << strSeqs << endl;
2
Bojan Komazec

vous essayez de renvoyer un vecteur et votre méthode doit renvoyer une chaîne. peut-être devez-vous changer une signature de méthode en

vector<string> getseq(char * db_file)
1
DesignFirst

Eh bien, vous essayez de renvoyer un vecteur sous forme de chaînes. Cela ne fonctionnera pas car ils sont de types différents et n'ont pas de conversion définie de l'un à l'autre. Votre fonction a le type de retour string.

Solution 1

Dans votre cas, vous pourriez ajouter les lignes à une chaîne au lieu de les ajouter à un vecteur? Vous utilisez de toute façon le résultat sous forme de chaîne.

Vous pouvez changer les séquences en string et y ajouter des données avec le += opérateur.

Solution 2

Vous pouvez également modifier le type de retour en vector<string> mais vous devrez faire une boucle sur les éléments et les imprimer à la place dans votre main.

vector<string> getseq(char * db_file)
{
    ...
    return seqs;
}

Attention Lector: ceci copiera tous les éléments. Si vous voulez éviter cela, passez le vecteur comme référence à la fonction et ajoutez-y.

Le bouclage est assez simple avec les itérateurs:

// Get the strings as a vector. 
vector<string> seqs = getseq(argv[1]);

// This is just a matter of taste, we create an alias for the vector<string> iterator type.
typedef vector<string>:iterator_t string_iter;

// Loop till we hit the end of the vector.
for (string_iter i = seqs.begin(); i != seqs.end(); i++)
{
   cout << *i; // you could add endlines, commas here etc.
}

Si vous voulez éviter de copier un vecteur et que toutes les chaînes font que getseq prenne une référence à un vector<string>.

void getseq(char * db_file, vector<string> &seqs)
{
    ...
    // vector<string> seqs; this line is not needed anymore.

    ...
    // we don't need to return anything anymore
}

Vous devrez alors créer le vector<string> dans votre main à la place, en créant mon code ci-dessus:

// Get the strings as a vector. 
vector<string> seqs;   // Holds our strings.
getseq(argv[1], seqs); // We don't return anything.

// This is just a matter of taste, we create an alias for the vector<string> iterator type.
typedef vector<string>:iterator_t string_iter;

// Print prelude.
cout << "Sekwencje: \n";

// Loop till we hit the end of the vector.
for (string_iter i = seqs.begin(); i != seqs.end(); i++)
{
   cout << *i << " "; // Do processing, add endlines, commas here etc.
}

cout << endl;

Modifier après les commentaires

int main(int argc, char * argv[1])
{
    // This is what you need, sorry for the confusion. 
    // This copies the vector returned to seqs
    vector<string> seqs = getseq(argv[1]); 

    // This is just a matter of taste, we create an alias for the vector<string> iterator type.
    typedef vector<string>::iterator string_iter;

    // Print prelude.
    cout << "Sekwencje: \n";

    // Loop till we hit the end of the vector.
    for (string_iter i = seqs.begin(); i != seqs.end(); i++)
    {
        cout << *i << " "; // Do processing, add endlines, commas here etc.
    }

    cout << endl;
}
1
Skurmedel