2011-02-03 18 views
9

मुझे एक फ़ंक्शन मिला है जो फ़ाइल लाइन से लाइन लाइन से पढ़ना चाहिए, जब कोई पंक्ति '>' या '' 'से शुरू नहीं होती है तो पढ़ना बंद हो जाता है। इसे वेक्टर में लाइनों को स्टोर करना चाहिए और इसे वापस करना चाहिए।
फ़ंक्शन में वेक्टर - वापसी कैसे करें

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

संकलक (छ ++) देता है:

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` 

कोई भी किसी भी विचार है
इस कोड है?

संपादित करें: Skurmendel से पूछते हैं, मैं स्मृति सुरक्षा उल्लंघन के कारण पूरे कोड जोड़ने हूँ के बाद

कोड संकलित क्रियान्वित के रूप में:

#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

आप क्या वापस करना चाहते हैं: यह अधिक कुशल अगर आपके स्ट्रिंग बाहर पैरामीटरके रूप में घोषित किया जाता है, जो आपने अभी समारोह के अंदर भरने हो सकता है? वेक्टर या स्ट्रिंग? – SuperSaiyan

+2

[मत] [http://stackoverflow.com/questions/4881210/how-to-convert-a-string-to-a-ifstream/4881251#4881251) [while] का उपयोग करें (http: // stackoverflow। कॉम/प्रश्न/4324441/getlinestreamobj-line-reads-last-line-multiple-times/4324667 # 4324667) (स्ट्रीम। [अच्छा] (http://stackoverflow.com/questions/4874530/fstream-unix-problem-in -reading/4874650 # 4874650)())। –

+0

@ थ्रस्टमास्टर: वेक्टर @ फ्रेड नर्क: इसके बजाय मुझे और क्यों उपयोग करने की आवश्यकता है? –

उत्तर

8

के बाद तो मैं समझ गया:

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 
} 

फिर आप के बजाय अपने मुख्य में vector<string> बनाने के लिए है, जिससे मेरे ऊपर कोड की आवश्यकता होगी आप, आपके getseq() तारों का एक वेक्टर वापस करना चाहिए। इसलिए आप

string getseq(char * db_file) 

बदलना चाहिए

vector<string> getseq(char * db_file) 

लिए और अगर आप मुख्य पर प्रिंट करना चाहते हैं() आप एक पाश में यह करना चाहिए।

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

या फिर एक लूप के बजाय बेहतर: 'std :: copy (str_vec.begin(), str_vec.end(), std :: ostream_iterator (cout," \ n "));'। –

+0

मैंने कोशिश की है लेकिन मुझे नीचे वर्णित त्रुटि (Skurmedel उत्तर के नीचे) मिलती है। –

+0

ठीक है, यह परिणाम काम करता है, अब मैं अनुक्रमों को पुनः प्राप्त करता हूं! सबको धन्यवाद! ;] मैं वास्तव में आपकी भागीदारी की सराहना करता हूं। ;] –

1

आप एक वेक्टर वापस जाने के लिए कोशिश करते हैं और अपने विधि लौटना चाहिए स्ट्रिंग। हो सकता है आप अच्छी तरह से

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

मैंने यह किया है, thx। ऊपर परिणाम। ;) –

1

लिए विधि का एक हस्ताक्षर बदलने के लिए है, तो आप तारों के रूप में एक सदिश वापस जाने के लिए कोशिश कर रहे हैं। यह काम नहीं करेगा क्योंकि वे अलग-अलग प्रकार हैं और एक से दूसरे में कोई रूपांतरण परिभाषित नहीं किया गया है। आपके फ़ंक्शन में वापसी प्रकार string है।

समाधान 1

आपके मामले में आप उन्हें एक वेक्टर को जोड़ने के बजाय एक स्ट्रिंग के लिए पंक्तियां जोड़ सकता है? आप किसी भी तरह एक स्ट्रिंग के रूप में परिणाम का उपयोग कर रहे हैं।

आप seqs को string में बदल सकते हैं और += ऑपरेटर के साथ डेटा जोड़ सकते हैं।

समाधान 2

तुम भी vector<string> को वापसी प्रकार बदल सकता है, लेकिन आप से अधिक आइटम पाश की जरूरत है और उन्हें अपने main में बजाय मुद्रित होगा।

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

चेतावनी पाठभेद: इस सभी आइटम कॉपी कर देंगे। यदि आप कार्य को संदर्भ के रूप में वेक्टर से गुजरना चाहते हैं और इसमें जोड़ना चाहते हैं।

पाशन 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. 
} 

आप एक वेक्टर कॉपी करने से बचना चाहते हैं और सभी स्ट्रिंग्स getseq एक vector<string> के लिए एक संदर्भ लेना सुनिश्चित करें।

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

संपादित टिप्पणियों

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

इस सलाह के लिए धन्यवाद! मैं इसे केवल यह जांचने के लिए प्रवण करना चाहता हूं कि क्या यह रेखाओं को लिखता है या नहीं। कार्यक्रम में मैं यह वेक्टर रखना चाहता हूं क्योंकि मैं पुनरावृत्ति करना चाहता हूं और वेक्टर वस्तुओं पर कुछ संचालन करना चाहता हूं - यह कुछ जैविक अनुक्रम होंगे। –

+0

मैटेयूज़ के: ठीक है :) मैंने अपने जवाब में थोड़ा और मांस जोड़ा। – Skurmedel

+0

धन्यवाद। :) दुर्भाग्य से मैंने इसे संकलित करने के बाद, और निष्पादित (./fpars seqs.fasta) यह कुछ संकेत देता है (जैसे बाइनरी फ़ाइल में) और कथन: स्मृति सुरक्षा का उल्लंघन। मेरे पास पॉलिश में यह कथन है इसलिए मुझे अंग्रेजी एनालॉग नहीं पता है। :/ –

1

आपका समारोह getseqstd::string वापस जाने के लिए घोषित किया जाता है, लेकिन आप एक और प्रकार का मान देने के लिए कोशिश कर रहे हैं - std::vector - इसलिए आपको लगता है कि संकलक त्रुटि मिली। आपको std::string (आपके वेक्टर के तत्वों को संयोजित करके बनाया गया) के चर को वापस करने की आवश्यकता है।

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

नोट:: यदि आप एक समारोह से लौट रहे हैं स्ट्रिंग बहुत बड़ा वस्तु और मूल्य से यह लौटने महंगा हो सकता है हो सकता है के रूप में क्या वास्तव में इस मामले में दिया जाता है है एक

आपका समारोह ऐसा दिखाई दे सकता उस वस्तु की प्रति (कॉपी कन्स्ट्रक्टर का आह्वान करके निर्मित)।

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

string strSeqs; 
getseq(argv[1], strSeqs); 
cout << strSeqs << endl; 
संबंधित मुद्दे