Reputation: 1057
I've got a function that should read from file line by line, the reading stops when a line does not begin with '>' or ' '. It should store the lines in vector and return it.
This is 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;
}
Compiler (g++) returns:
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`
Anyone has any idea?
Edit: As Skurmendel ask, I am adding whole code because of memory security violation after
executing compiled code:
#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;
}
Upvotes: 14
Views: 74988
Reputation: 2397
If I understood you, your getseq() should return a vector of strings. Therefore you should change
string getseq(char * db_file)
to
vector<string> getseq(char * db_file)
And if you want to print it on main() you should do it in a loop.
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;
}
}
Upvotes: 13
Reputation: 22179
Well, you are trying to return a vector as strings. This won't work because they are different types and have no conversion defined from one to the other. Your function has the return type string
.
Solution 1
In your case you could append the lines to a string instead of adding them to a vector? You are using the result as a string anyhow.
You could change seqs to string
and append data to it with the +=
operator.
Solution 2
You could also change the return type to vector<string>
but you would need to loop over the items and print them instead in your main
.
vector<string> getseq(char * db_file)
{
...
return seqs;
}
Caveat Lector: this will copy all the items. If you want to avoid this pass the vector as a reference to the function and add to it.
Looping is quite easy using iterators:
// 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.
}
If you want to avoid copying a vector and all the strings make getseq
take a reference to a 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
}
You would then need to create the vector<string>
in your main instead, making my above code:
// 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;
Edit after comments
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;
}
Upvotes: 1
Reputation: 9536
Your function getseq
is declared to return std::string
but you are trying to return value of another type - std::vector
- therefore you got that compiler error. You need to return variable of type std::string
(created by concatenating elements of your vector).
Your function could look like this:
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;
}
Note: string you are returning from a function can be quite big object and returning it by value can be expensive as what is actually returned in this case is a copy of that object (constructed by invoking copy constructor). It would be more efficient if your string is declared as out parameter which you just fill inside the function:
void getseq(char* db_file, string& strSeqs);
string strSeqs;
getseq(argv[1], strSeqs);
cout << strSeqs << endl;
Upvotes: 2
Reputation: 329
you try to return a vector and your method must return string. maybe you have to change a signature of method to
vector<string> getseq(char * db_file)
Upvotes: 1