c++ - 使用 3 个输入而不是 2 个输入时收到 malloc 错误
问题描述
这里的代码应该包含 dna 字母链/字符串('ATG' + 'CTA' = 'ATGCTA'),并能够将它们组合起来,并从组合链中减去特定部分。当用户必须输入两股时,组合工作正常,但是当有三股时,组合似乎中途被切断。任何帮助表示赞赏!
dnasequence.h
#include <iostream>
#include <string>
#ifndef _DNASEQUENCE_
#define _DNASEQUENCE_
using namespace std;
// class DNASequence
//
// A class that contains a sequence of nucleotides in the dna_sequence.
// The max_sequence represents the capacity of the dna_sequence.
// A dna_sequence is a c-string of characters that consist only of
// 'A', 'T', 'G', 'C' standing for the 4 nucleotides and ending in a '\0'
// character. Input into the DNASequence is case-insensitive meaning that
// lower or upper case is acceptable, but it should be converted to uppercase
// internally.
//
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
bool operator == (const DNASequence& arg);
// Equals operator compares the given sequence with the invoking object.
bool operator != (const DNASequence& arg);
// Not equals operator compares the given sequence with the invoking object.
friend DNASequence operator + (const DNASequence& arg1, const DNASequence& arg2);
// Append the given sequence onto the end of a copy of the invoking object sequence.
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);
// Implement the friend function to read in a nucleotide sequence made up
// of only the following characters: adenine (A), thymine (T), guanine (G)
// and cytosine (C). Assume case insensitive but convert to upper internally.
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()
{
this->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)
{
this->max_sequence = arg.get_max_sequence();
this->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)
{
this->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;
}
// Equals operator compares the given sequence with the invoking object.
bool DNASequence::operator == (const DNASequence& arg)
{
int i = 0, j = 0;
while (this->dna_sequence[i] !='\0' && arg.dna_sequence[j]!='\0')
{
if (this->dna_sequence[i] != arg.dna_sequence[j])
return false;
i++;
j++;
}
if (this->dna_sequence[i] == '\0' && arg.dna_sequence[j] == '\0')
return true;
return false;
}
bool DNASequence::operator != (const DNASequence& arg)
{
int i = 0, j = 0;
while (this->dna_sequence[i] != '\0' && arg.dna_sequence[j] != '\0')
{
if (this->dna_sequence[i] != arg.dna_sequence[j])
return true;
i++;
j++;
}
if (this->dna_sequence[i] == '\0' && arg.dna_sequence[j] == '\0')
return false;
return true;
}
// Append the given sequence onto the end of the invoking object sequence.
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. Return
// the modified sequence. If the given sequence is not found, return the
// first argument sequence unaltered.
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);
int i = 0;
for (int j = 0; j < arg1.get_max_sequence(); j++)
{
temp.dna_sequence[i] = arg1.dna_sequence[j];
i++;
}
for (int j = 0; j < arg2.get_max_sequence(); j++)
{
temp.dna_sequence[i] = arg2.dna_sequence[j];
i++;
}
temp.dna_sequence[i] = '\0';
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'
// return false if any characters in the string are different. You can
// use any means you like, remember what we did with palindrome code to
// avoid a big if statement.
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 nucleotide sequence made up
// of only the following characters: adenine (A), thymine (T), guanine (G)
// and cytosine (C). Assume case insensitive but convert to upper internally.
istream& operator >> (istream& ins, DNASequence& arg)
{
// Read in a string and use the validate function above to ensure that
// the string has only nucleotides and convert them all to upper case.
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';
}
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
/*
* Test driver for DNAStrand with DNASequences
*
*
*
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "dnasequence.h"
using namespace std;
// int main()
//
// Implements the driver for the DNAStrand testing using DNASequences.
//
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];
}
/*
cout << DNA[0];
cout << endl;
cout << DNA[1];
cout << endl;
DEBUG LINES
*/
// 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;
// 6 a. Test == operator
cout << "Checking == operator ... " << endl;
if(big_strand == clean_strand)
cout << "Functioning properly\n";
// 6 b. Test != operator
cout << "Checking != operator... " << endl;
if (big_strand != bad_dna)
cout << "Functioning properly\n";
// 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;
}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;
// 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;
}
解决方案
推荐阅读
- ios - 当标签栏的标签/视图控制器发生变化时,如何更新标签?(迅速)
- excel - Excel公式:对于列中峰值/谷值的每个实例,获取到下一个峰值/谷值的范围/距离
- python - Heroku App 可以在本地与 Heroku-postgres 交互,但在部署到 Heroku 时不能
- stanford-nlp - 孤立地(在句子之外)标记上的附随词的标记化
- ios - 如何理解 AVPlayerItem 及其与 AVPlayerItemVideoOutput 相关的当前时间
- stenciljs - StencilJS 中的 xml2Js
- python-3.x - 如何使用python打印饼图外的百分比
- sqlite - 如何编写 Fluent NHibernate 约定来指定所有实体的标识符?
- python - 绘制固定一点的双点
- apache - 阿帕奇 mod_jk | Virtualhost 不监听域名将请求转发到 Tomcats