c++ - 从友元函数返回后无法输出动态数组

标签 c++ class dynamic overloading

有一个 dna 类,我们在其中向 big_strand 添加一些输入(似乎有效)。然后取另一个输入并从 big_strand 中减去它。只要我在减法函数中输出,这似乎就可以工作。然而,在返回 temp 并返回 main 后,输出只是给出一个空行(图像中的灰线是我突出显示的空行)。任何帮助表示赞赏。

dnasequence.h

#include <iostream>
#include <string>

#ifndef _DNASEQUENCE_
#define _DNASEQUENCE_
using namespace std;


class DNASequence 
{
    public:
        DNASequence(); 
        // Assume that the strand is made up of 100 sequences.

        DNASequence(string nucleotides);
        // Assume that the sequence is initialized to the nucleotides string.

        DNASequence(const DNASequence& arg);
        // Copy constructor

        ~DNASequence();
        // Destructor

        DNASequence& operator = (const DNASequence& arg);
        // Assignment operator

        friend DNASequence operator + (const DNASequence& arg1, const DNASequence& arg2);
        
        friend DNASequence operator - (const DNASequence& arg1, const DNASequence& arg2);
        // Remove the given sequence from a copy of the invoking object if it exists. Return
        // the modified sequence. If the given sequence is not found, return the
        // invoking sequence unaltered.
        
        //checks if string is valid
        bool isitvalid(string str);

        friend istream& operator >> (istream& ins, DNASequence& arg);
        friend ostream& operator << (ostream& out, const DNASequence& arg);
        // Implement the friend function to write out a nucleotide sequence. No blanks.
        
        
        int get_max_sequence() const { return max_sequence; };
        // Accessor for max_sequence.

        char* get_dna_sequence() const { return dna_sequence; };
        // Accessor for dna_sequence.

    private:
        char* dna_sequence;    // Dynamic array of char
        int max_sequence; // Maximum number of nucleotides.
        
};

#endif
dnasequence.cpp

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include "dnasequence.h"

using namespace std;

// Assume that the strand is made up of 100 sequences.
DNASequence::DNASequence() 
{
    dna_sequence = new char[101]; // 100 + null
    dna_sequence = new char[101]; // 100 + null
    max_sequence = 0;
}

// Assume that the sequence is initialized to the nucleotides string.
DNASequence::DNASequence(string nucleotides) 
{
    int i;
    dna_sequence = new char[nucleotides.length()+1];
    for(i = 0; i < nucleotides.length(); i++)
    {
        dna_sequence[i] = nucleotides.at(i);
    }
    dna_sequence[i] = '\0'; // Changed
    max_sequence = nucleotides.length();
    //cout << max_sequence << endl;
}

// Copy constructor
DNASequence::DNASequence(const DNASequence& arg)
{
   max_sequence = arg.get_max_sequence();
   dna_sequence = new char[/*this->*/max_sequence+1];
   int i = 0;
   for (i = 0; i < /*this->*/max_sequence; i++)
       dna_sequence[i] = arg.dna_sequence[i];
   dna_sequence[i] = '\0';
}

// Destructor
DNASequence::~DNASequence()
{
    delete [] dna_sequence;
}

// Assignment operator
DNASequence& DNASequence::operator = (const DNASequence& arg)
{
   max_sequence = arg.get_max_sequence();
   dna_sequence = new char[/*this->*/max_sequence+1];
   int i = 0;
   for (i = 0; i < /*this->*/max_sequence; i++)
   {
       dna_sequence[i] = arg.dna_sequence[i];
   }
   dna_sequence[i] = '\0';
   return *this;
}
DNASequence operator + (const DNASequence& arg1, const DNASequence& arg2)
{
   DNASequence temp = arg1;
   if (arg1.get_max_sequence() == 0)
       return arg2;
   if (arg2.get_max_sequence() == 0)
       return arg1;

   temp.max_sequence = arg1.get_max_sequence() + arg2.get_max_sequence();
   temp.dna_sequence = new char[temp.max_sequence + 1];
   //cout << temp.max_sequence;
   int i = 0;
   for (int j = 0; j < arg1.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg1.dna_sequence[j];
       i++;
       //cout << i << endl; debug line
   }
   //i++; // changed

   for (int j = 0; j < arg2.get_max_sequence(); j++)
   {
       temp.dna_sequence[i] = arg2.dna_sequence[j];
       i++;
       //cout << i << endl; debug line
   }
   temp.dna_sequence[i] = '\0'; // changed to i + 1
   return temp;
}

// Remove the given sequence from the invoking object if it exists.
DNASequence operator - (const DNASequence& arg1, const DNASequence& arg2)
{
    // arg1 is the big strand
    // arg2 is strand to be deleted
    DNASequence temp;
    int x = 0;
   if (arg1.get_max_sequence() == 0)
       return arg2;
   if (arg2.get_max_sequence() == 0)
       return arg1;
    
    int found = -1;
    string s1, s2;
        
   for(int i = 0; i < arg1.get_max_sequence(); i++)
   {
       s1 = s1 + arg1.dna_sequence[i];
   }
   for(int i = 0; i < arg2.get_max_sequence(); i++)
   {
       s2 = s2 + arg2.dna_sequence[i]; 
   }
    do
    {
        found = s1.find(s2, found + 1);
        if(found != -1)
        {
            s1 = s1.substr(0, found) + s1.substr(found + s2.length());
        }
        
    }while(found != -1);
    for(int i = 0; i < s1.length(); i++)
   {
       temp.dna_sequence[i] = s1[i];
   }
  
   return temp;
}

// check if string is valid
bool DNASequence::isitvalid(string str) 
{
   // Check the string for characters 'A', 'a', 'T', 't', 'G', 'g', 'C', 'c'
   bool valid = false;
   for (int i = 0; i < str.length(); i++)
   {
       if (str[i] != 'A' && str[i] != 'a' && str[i] != 'T' && str[i] != 't' && str[i] != 'G' && str[i] != 'g' && str[i] != 'C' && str[i] != 'c')
           return false;          
   }
   return true;
}

// Implement the friend function to read in a nucleotides A, C, T, G and check if uppercase
istream& operator >> (istream& ins, DNASequence& arg)
{
   string str;
   ins >> str;
   if (arg.isitvalid(str))
   { 
       arg.max_sequence = str.length();
       arg.dna_sequence = new char[str.length()+1];
       int i = 0;
       for (i = 0; i < str.length(); i++)
       {
           arg.dna_sequence[i] = toupper(str[i]);
       }
       arg.dna_sequence[i] = '\0';
   }
   //delete [] arg.dna_sequence;
   return ins;
}

// Implement the friend function to write out a nucleotide sequence. No blanks.
ostream& operator << (ostream& out, const DNASequence& arg)
{
   for (int i = 0; i < arg.get_max_sequence(); i++)
   {
       out << arg.dna_sequence[i];
   }
   out << endl;
   return out;
}
dna_main.cpp

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "dnasequence.h"

using namespace std;


int main()
{
    int i = 0;
    int n;
    char rerun;
    // Implement your test functions here.

    //greeting 
    cout << "Welcome to CRISPR!" <<endl;
    cout << endl;
    do
    {
        
    
    // 1. Start a do-while loop that spans the rest of the instructions.
    
    // 2. Ask the user to enter the number of DNASequences needed for the CRISPR application.
        cout << "Enter the number of DNA sequences needed: ";
        cin >> n;
        
        // 3. Either declare a vector of DNASequence or a dynamic array where the user enters the number of elements.
        vector<DNASequence>DNA(n); //?

    // 4. In a for-loop, read in a DNASequence for each element in the array using >> operator.
        for(i = 0; i < n; i++)
         {
             cout << "Processing DNA sequence #" << i + 1 << endl;
             cout << "Enter the elements in sequence #" << i + 1 << ": ";
             cin >> DNA[i];  
         }
       
    // 5. Declare a DNASequence called big_strand and add each element in the array to big_strand in a for-loop.
            
            DNASequence big_strand;
        
            for(int x = 0; x < n ; x++)
            { 
                big_strand = big_strand + DNA[x];
            }

    // 6. Print the final big_strand after the loop using the << operator.

        cout << "The contents in the big strand is: ";
        cout << big_strand;
        
    // 7. Declare two variables: one for a small sequence of bad_dna and one to hold the clean_strand.
       // NOTE: Make sure that clean_strand is set directly to big_strand when declared.
         
           DNASequence bad_dna;
           DNASequence clean_strand = big_strand;
           //DNASequence clean_strand;

        

    
    
    // 8. Ask the user to enter the bad DNASequence to remove from big_strand and put it in the bad_dna variable.
      
        cout << "Enter a bad DNASequence to remove from big_strand: ";
        cin >> bad_dna;
       

    // 9. In a do-while loop add the following lines

        // 9 a. set the big_strand to the clean_strand
        // 9 b. subtract the bad_dna from big_strand and put the result in clean_strand
          do
          {
            //big_strand = clean_strand;
            clean_strand = big_strand - bad_dna;
            cout << clean_strand;
            cout << clean_strand.get_dna_sequence();
          }while(clean_strand != big_strand);
           

    // 10. Use clean_strand != big_strand as the while condition so that it loops until the big_strand is clean.

    // 11. Print the clean_strand as you go and the final result.

        cout << "The contents in the clean strand is: " ; 
        //cout << clean_strand;
        //cout << clean_strand.get_dna_sequence();

    // 12. Test operator% with a copy of the big_strand to see if the result is the same as the loop above.

    // 13. Clean up array/vector
        DNA.clear();
    // 14. Ask the user to try again.
    
        cout << "Would you like to try again (y/n)?";
        cin >> rerun;

    }while(rerun == 'y' || rerun == 'Y');
    return 0;
}


最佳答案

您从未在operator- 中设置temp.max_sequence,因此它会报告长度为零。

此外,您不会像在 operator+ 中那样在序列末尾放置一个零字节。

关于c++ - 从友元函数返回后无法输出动态数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59166811/

相关文章:

c++ - 使用复制构造函数的程序输出错误

c++ - 在 stm32 上使用调试器 swo

class - 多态到底是什么?

java - 为什么调用不同类的 main 方法无法正常工作?

c++ - 在动态分配的指针数组中扩展内存

javascript - Jquery 根据值添加元素

c# - 为什么这种明显的无限递归不给出编译器警告?

c++ - 这是 glGetTexParameterIuiv 的错误或预期行为吗?

python - 动态分配模块名称作为别名

java - 切换主题时如何考虑变化?