C++ 函数中的向量 - 如何返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4885854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:50:57  来源:igfitidea点击:

vector in function - how to do return

c++vectorreturn-valuereturn

提问by Mateusz Korycinski

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:

编译器 (g++) 返回:

    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

编辑:正如 Skurmendel 所问,由于内存安全违规,我添加了整个代码

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;
}

采纳答案by vtorhonen

If I understood you, your getseq() should return a vector of strings. Therefore you should change

如果我理解你,你的 geteq() 应该返回一个字符串向量。因此你应该改变

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.

如果你想在 main() 上打印它,你应该在循环中进行。

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;
     }
}

回答by Bojan Komazec

Your function getseqis declared to return std::stringbut 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).

您的函数getseq被声明为返回,std::string但您正在尝试返回另一种类型的值std::vector- 因此您遇到了编译器错误。您需要返回类型变量std::string(通过连接向量的元素创建)。

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 parameterwhich you just fill inside the function:

注意:您从函数返回的字符串可能是相当大的对象,并且按值返回它可能很昂贵,因为在这种情况下实际返回的是该对象的副本(通过调用复制构造函数构造)。如果您的字符串被声明为您只是在函数内部填充的out 参数,则效率会更高:

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

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

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

回答by DesignFirst

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)

回答by Skurmedel

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.

好吧,您正在尝试将向量作为字符串返回。这是行不通的,因为它们是不同的类型,并且没有定义从一种到另一种的转换。您的函数具有返回类型string

Solution 1

解决方案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 stringand append data to it with the +=operator.

您可以string使用+=运算符将seqs 更改为并向其附加数据。

Solution 2

解决方案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>但您需要遍历项目并在您的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.

警告 Lector:这将复制所有项目。如果您想避免这种情况,请将向量作为对函数的引用并添加到它。

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 getseqtake a reference to a vector<string>.

如果您想避免复制向量并且所有字符串都getseq引用 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:

然后vector<string>,您需要在 main 中创建,使我上面的代码:

// 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;
}