用VC++6.0写了一个十字链表矩阵转置的程序,想把它移植到linux下.
有两个版本第一个用的纯粹是C,后缀为.CPP,直接g++编译通过,而后来一个改进的版本,采用iostream流类,则报告出错,错误信息如下:
200528004133043.cpp: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/ios_base.h:779: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
200528004133043.cpp:191: error: within this context
200528004133043.cpp: In copy constructor ‘std::basic_filebuf<char, std::char_traits<char> >::basic_filebuf(const std::basic_filebuf<char, std::char_traits<char> >&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/streambuf:772: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’ is private
200528004133043.cpp:191: error: within this context
200528004133043.cpp: In function ‘int main(int, char**)’:
200528004133043.cpp:191: error: initializing argument 1 of ‘bool CreatSMatrix(std::ifstream, CrossList&)’
查找后发现原来是creatMatrix函数的第一个形参 采用 直接读入,而不是引用的 方式,修正后问题解决.
原程序如下:
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
typedef struct OLNode{ //data struct
int r,c; //nonzero's row and column
float e; //nonzero's value
struct OLNode * right,* down; //next element
}Node,*OLink;
typedef struct{ //crosslist struct
OLink *rhead,*chead; //link to row and column's head
int row,column,nzero; //matrix's row,column and number of nonzero
}CrossList;
bool CreatSMatrix(ifstream &in,CrossList &M)
{
int row,column,nzero;
int i,r,c; //temp varies
float value;
Node *Matrix;
Node *q;
in>>row>>column>>nzero; //scanf matrix's row,column and number of nonzero from file
if(row<=0||column<=0||nzero<=0)
{
cout<<"Haven't any nonzero number!/n";
return false; //return input error
}
M.row=row;
M.column=column;
M.nzero=nzero;
M.rhead=new OLink[row];
M.chead=new OLink[column];
for(i=0;i<row;i++)
M.rhead[i]=NULL; //initialize rhead and chead to NULL
for(i=0;i<column;i++)
M.chead[i]=NULL;
for(;nzero>0;nzero--)
{
in>>r>>c>>value; //scanf data from file
Matrix=(Node *)new Node; //produce node
Matrix->r=r;
Matrix->c=c;
Matrix->e=value;
Matrix->right=NULL;
Matrix->down=NULL;
if(M.rhead[r]==NULL)
M.rhead[r]=Matrix;
else
{ //find the location for inserting in row
q=M.rhead[r];
if(q->c>c)
{
M.rhead[r]=Matrix;
Matrix->right=q;
}
else
{
for(;(q->right)&&(q->right->c<c);q=q->right);
Matrix->right=q->right;
q->right=Matrix;
}
}
if(M.chead[c]==NULL)
M.chead[c]=Matrix;
else
{ //find the location for inserting in column
q=M.chead[c];
if(q->r>r)
{
M.chead[c]=Matrix;
Matrix->down=q;
}
else
{
for(;(q->down)&&(q->down->r<r);q=q->down);
Matrix->down=q->down;
q->down=Matrix;
}
}
}
return true;
}
void TranseSMatrix(CrossList &M,CrossList &TM)
{
Node *p,*q;
int i;
TM.row=M.column;
TM.column=M.row;
TM.rhead=new OLink[TM.row];
TM.chead=new OLink[TM.column];
Node *TMatrix;
for(i=0;i<TM.row;i++) //initialize rhead and chead to NULL
TM.rhead[i]=NULL;
for(i=0;i<TM.column;i++)
TM.chead[i]=NULL;
for(i=0;i<M.row;i++) //traverse by row
{
if(M.rhead[i]==NULL);
else
{
q=M.rhead[i];
for(;(q);q=q->right)
{
TMatrix=(Node *)new Node;
TMatrix->r=q->c; //exchange the position of row and column
TMatrix->c=q->r;
TMatrix->e=q->e;
TMatrix->right=NULL;
TMatrix->down=NULL;
if(TM.rhead[TMatrix->r]==NULL)
TM.rhead[TMatrix->r]=TMatrix;
else //find the location for inserting in row
{
p=TM.rhead[TMatrix->r];
for(;(p->right)&&(p->right->c<TMatrix->c);p=p->right);
TMatrix->right=p->right;
p->right=TMatrix;
}
if(TM.chead[TMatrix->c]==NULL)
TM.chead[TMatrix->c]=TMatrix;
else //find the location for inserting in column
{
p=TM.chead[TMatrix->c];
for(;(p->down)&&(p->down->r<TMatrix->r);p=p->down);
TMatrix->down=p->down;
p->down=TMatrix;
}
}
}
}
}
void printSMatrix(CrossList &M)
{
Node *qM=NULL; //creat a temp node
int i,j;
for(i=0;i<M.row;i++)
{
if(M.rhead[i] !=NULL) //
qM=M.rhead[i];
for(j=0;j<M.column;j++)
{
if(qM!=NULL)
{
if(qM->c==j) //if match, print value
{
cout<<setw(4)<<setprecision(2)<<qM->e;
qM=qM->right;
}
else cout<<setw(4)<<"0"; //
}
else cout<<setw(4)<<"0"; //put NULL link to 0
if(j==M.column-1)
cout<<"/n";
}
}
cout<<"/n";
}
int main(int argc,char *argv[])
{
ifstream in;
if(argc==1)
{
cout<<"Haven't enter file name!/n/n";
return false;
}
in.open(argv[1]);
if(!in)
{
cout<<"Cannot open "<<argv[1]<<"/n";
return false;
}
cout<<"Name: No: /n/n";
CrossList M,TM;
if(!CreatSMatrix(in,M))
{
in.close();
return 0;
}
in.close();
cout<<"SMatrix/n";
printSMatrix(M);
TranseSMatrix(M,TM);
cout<<"TranseSMatrix/n";
printSMatrix(TM);
return 1;
}
原来的C版本中,creatMatrix(File *f,XXX) 故不会报错,而VC++ 6.0版本较早,所以能够通过win下的编译.
此外,不知为什么在vi中总会自动加上很多^M符号
有两个版本第一个用的纯粹是C,后缀为.CPP,直接g++编译通过,而后来一个改进的版本,采用iostream流类,则报告出错,错误信息如下:
200528004133043.cpp: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/ios_base.h:779: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
200528004133043.cpp:191: error: within this context
200528004133043.cpp: In copy constructor ‘std::basic_filebuf<char, std::char_traits<char> >::basic_filebuf(const std::basic_filebuf<char, std::char_traits<char> >&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/streambuf:772: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’ is private
200528004133043.cpp:191: error: within this context
200528004133043.cpp: In function ‘int main(int, char**)’:
200528004133043.cpp:191: error: initializing argument 1 of ‘bool CreatSMatrix(std::ifstream, CrossList&)’
查找后发现原来是creatMatrix函数的第一个形参 采用 直接读入,而不是引用的 方式,修正后问题解决.
原程序如下:
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
typedef struct OLNode{ //data struct
int r,c; //nonzero's row and column
float e; //nonzero's value
struct OLNode * right,* down; //next element
}Node,*OLink;
typedef struct{ //crosslist struct
OLink *rhead,*chead; //link to row and column's head
int row,column,nzero; //matrix's row,column and number of nonzero
}CrossList;
bool CreatSMatrix(ifstream &in,CrossList &M)
{
int row,column,nzero;
int i,r,c; //temp varies
float value;
Node *Matrix;
Node *q;
in>>row>>column>>nzero; //scanf matrix's row,column and number of nonzero from file
if(row<=0||column<=0||nzero<=0)
{
cout<<"Haven't any nonzero number!/n";
return false; //return input error
}
M.row=row;
M.column=column;
M.nzero=nzero;
M.rhead=new OLink[row];
M.chead=new OLink[column];
for(i=0;i<row;i++)
M.rhead[i]=NULL; //initialize rhead and chead to NULL
for(i=0;i<column;i++)
M.chead[i]=NULL;
for(;nzero>0;nzero--)
{
in>>r>>c>>value; //scanf data from file
Matrix=(Node *)new Node; //produce node
Matrix->r=r;
Matrix->c=c;
Matrix->e=value;
Matrix->right=NULL;
Matrix->down=NULL;
if(M.rhead[r]==NULL)
M.rhead[r]=Matrix;
else
{ //find the location for inserting in row
q=M.rhead[r];
if(q->c>c)
{
M.rhead[r]=Matrix;
Matrix->right=q;
}
else
{
for(;(q->right)&&(q->right->c<c);q=q->right);
Matrix->right=q->right;
q->right=Matrix;
}
}
if(M.chead[c]==NULL)
M.chead[c]=Matrix;
else
{ //find the location for inserting in column
q=M.chead[c];
if(q->r>r)
{
M.chead[c]=Matrix;
Matrix->down=q;
}
else
{
for(;(q->down)&&(q->down->r<r);q=q->down);
Matrix->down=q->down;
q->down=Matrix;
}
}
}
return true;
}
void TranseSMatrix(CrossList &M,CrossList &TM)
{
Node *p,*q;
int i;
TM.row=M.column;
TM.column=M.row;
TM.rhead=new OLink[TM.row];
TM.chead=new OLink[TM.column];
Node *TMatrix;
for(i=0;i<TM.row;i++) //initialize rhead and chead to NULL
TM.rhead[i]=NULL;
for(i=0;i<TM.column;i++)
TM.chead[i]=NULL;
for(i=0;i<M.row;i++) //traverse by row
{
if(M.rhead[i]==NULL);
else
{
q=M.rhead[i];
for(;(q);q=q->right)
{
TMatrix=(Node *)new Node;
TMatrix->r=q->c; //exchange the position of row and column
TMatrix->c=q->r;
TMatrix->e=q->e;
TMatrix->right=NULL;
TMatrix->down=NULL;
if(TM.rhead[TMatrix->r]==NULL)
TM.rhead[TMatrix->r]=TMatrix;
else //find the location for inserting in row
{
p=TM.rhead[TMatrix->r];
for(;(p->right)&&(p->right->c<TMatrix->c);p=p->right);
TMatrix->right=p->right;
p->right=TMatrix;
}
if(TM.chead[TMatrix->c]==NULL)
TM.chead[TMatrix->c]=TMatrix;
else //find the location for inserting in column
{
p=TM.chead[TMatrix->c];
for(;(p->down)&&(p->down->r<TMatrix->r);p=p->down);
TMatrix->down=p->down;
p->down=TMatrix;
}
}
}
}
}
void printSMatrix(CrossList &M)
{
Node *qM=NULL; //creat a temp node
int i,j;
for(i=0;i<M.row;i++)
{
if(M.rhead[i] !=NULL) //
qM=M.rhead[i];
for(j=0;j<M.column;j++)
{
if(qM!=NULL)
{
if(qM->c==j) //if match, print value
{
cout<<setw(4)<<setprecision(2)<<qM->e;
qM=qM->right;
}
else cout<<setw(4)<<"0"; //
}
else cout<<setw(4)<<"0"; //put NULL link to 0
if(j==M.column-1)
cout<<"/n";
}
}
cout<<"/n";
}
int main(int argc,char *argv[])
{
ifstream in;
if(argc==1)
{
cout<<"Haven't enter file name!/n/n";
return false;
}
in.open(argv[1]);
if(!in)
{
cout<<"Cannot open "<<argv[1]<<"/n";
return false;
}
cout<<"Name: No: /n/n";
CrossList M,TM;
if(!CreatSMatrix(in,M))
{
in.close();
return 0;
}
in.close();
cout<<"SMatrix/n";
printSMatrix(M);
TranseSMatrix(M,TM);
cout<<"TranseSMatrix/n";
printSMatrix(TM);
return 1;
}
原来的C版本中,creatMatrix(File *f,XXX) 故不会报错,而VC++ 6.0版本较早,所以能够通过win下的编译.
此外,不知为什么在vi中总会自动加上很多^M符号