2011-02-03 27 views
9

Tôi có chức năng đọc từ dòng tệp theo dòng, việc đọc sẽ dừng khi một dòng không bắt đầu bằng '>' hoặc ''. Nó sẽ lưu trữ các dòng trong vector và trả về nó.
Đây là mã:
vectơ đang hoạt động - cách thực hiện trả lại

#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 ++) trả về:

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` 

Bất cứ ai có bất kỳ ý tưởng?

Edit: Như Skurmendel hỏi, tôi đang bổ sung toàn bộ mã vì vi phạm an ninh bộ nhớ sau khi

thực hiện biên dịch mã:

#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; 
} 
+2

Những gì bạn muốn quay trở lại? Các vector hoặc chuỗi? – SuperSaiyan

+2

[Không] (http://stackoverflow.com/questions/4881210/how-to-convert-a-string-to-a-ifstream/4881251#4881251) sử dụng [trong khi] (http: // stackoverflow. com/questions/4324441/getlinestreamobj-line-lần đọc-last-line-nhiều lần/4324667 # 4324667) (luồng. [tốt] (http://stackoverflow.com/questions/4874530/fstream-unix-problem-in -reading/4874650 # 4874650)()). –

+0

@Thrustmaster: vector @Fred Nurk: Tại sao và những gì tôi cần phải sử dụng thay thế? –

Trả lời

8

Nếu tôi hiểu bạn, getseq() của bạn sẽ trả về một vectơ của chuỗi. Vì vậy, bạn nên thay đổi

string getseq(char * db_file) 

để

vector<string> getseq(char * db_file) 

Và nếu bạn muốn in nó trên main() bạn nên làm điều đó trong một vòng lặp.

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

Hoặc tốt hơn, thay vì một vòng lặp: 'std :: copy (str_vec.begin(), str_vec.end(), std :: ostream_iterator (cout," \ n "));'. –

+0

Tôi đã thử nhưng tôi nhận được lỗi tương tự như mô tả dưới đây (dưới Skurmedel câu trả lời). –

+0

Ok, kết quả này hoạt động, bây giờ tôi lấy chuỗi! Cảm ơn vì tất cả! ;] Tôi thực sự đánh giá cao sự tham gia của bạn. ;] –

1

bạn cố gắng để trở về một vector và phương pháp của bạn phải trả lại chuỗi. có thể bạn phải thay đổi chữ ký của phương thức thành

vector<string> getseq(char * db_file) 
+0

Tôi đã làm điều này, thx. Kết quả ở trên. ;) –

1

Vâng, bạn đang cố gắng trả lại vectơ dưới dạng chuỗi. Điều này sẽ không hoạt động vì chúng là các loại khác nhau và không có chuyển đổi được xác định từ một đến khác. Hàm của bạn có kiểu trả về là string.

Giải pháp 1

Trong trường hợp của bạn, bạn có thể thêm các dòng vào một chuỗi thay vì bổ sung chúng vào một vectơ? Bạn đang sử dụng kết quả dưới dạng chuỗi.

Bạn có thể thay đổi seq thành string và nối dữ liệu vào nó với toán tử +=.

Giải pháp 2

Bạn cũng có thể thay đổi kiểu trả về để vector<string> nhưng bạn sẽ cần phải lặp qua các mục và in chúng thay vì trong main của bạn.

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

Caveat Lector: điều này sẽ sao chép tất cả các mục. Nếu bạn muốn tránh điều này vượt qua vector như một tham chiếu đến hàm và thêm vào nó.

Looping là khá dễ dàng sử dụng vòng lặp:

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

Nếu bạn muốn tránh sao chép một vector và tất cả các chuỗi làm getseq mất một tham chiếu đến một 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 
} 

Sau đó, bạn sẽ cần phải tạo ra các vector<string> ở chính của bạn thay vào đó, làm cho mã trên tôi:

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

Chỉnh sửa sau khi bình luận

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

Cảm ơn lời khuyên này! Tôi muốn pront nó chỉ để kiểm tra xem nó đọc dòng wright. Trong chương trình tôi muốn có vector này bởi vì tôi muốn lặp lại và thực hiện một số thao tác trên các mục vectơ - nó sẽ là một số chuỗi sinh học. –

+0

Mateusz K: Ok :) Tôi đã thêm một chút xác thịt vào câu trả lời của tôi. – Skurmedel

+0

Cảm ơn. :) Unfortunatelly sau khi tôi đã biên dịch nó, và thực hiện (./fpars seqs.fasta) nó trả về một số dấu hiệu (như trong tệp nhị phân) và tuyên bố: Vi phạm về bảo mật bộ nhớ. Tôi có tuyên bố này trong đánh bóng vì vậy tôi không biết tiếng anh tương tự. :/ –

1

Chức năng của bạn getseq bị tuyên bố quay trở lại std::string nhưng bạn đang cố gắng để trở về giá trị của loại hình khác - std::vector - do đó bạn nhận rằng lỗi biên dịch. Bạn cần trả về biến loại std::string (được tạo bằng cách ghép các phần tử của vectơ của bạn).

chức năng bạn có thể trông như thế này:

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

Lưu ý: string bạn đang trở về từ một hàm có thể được đối tượng khá lớn và trở về nó bằng giá trị có thể tốn kém như những gì đang thực sự trở lại trong trường hợp này là một bản sao của đối tượng đó (được xây dựng bằng cách gọi hàm tạo bản sao). Sẽ hiệu quả hơn nếu chuỗi của bạn được khai báo là ra tham số mà bạn vừa điền vào bên trong hàm:

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

string strSeqs; 
getseq(argv[1], strSeqs); 
cout << strSeqs << endl; 
Các vấn đề liên quan