在我的班级文件中,我已经:
class File
{
std::vector<char> name, timeOfCreation, timeOfLastEdit, content;
std::vector<char>::const_iterator* pPos, *pPosOfEnd;
int *pSize;
bool *pForcedSize;
void setTimeOfLastEdit();
int* indexOfLastChar, *indexOfCurrentChar;
friend class Interface;
friend class Directory;
public:
File(std::string, int argSize = 0, std::string arg_content = 0); // constructor
File(); // constructor
File(const File&); // copy constructor
~File(); // destructor
char* returnName();
File& operator = (const File&);
File operator += (const int);
File operator -= (const int);
File& operator ++ (); // prefix
File& operator -- (); // prefix
File operator ++ (int); // postfix
File operator -- (int); // postfix
bool operator ! ();
int operator () (char*, int);
friend bool operator == (const File&, const File&);
friend bool operator != (const File&, const File&);
friend bool operator >= (const File&, const File&);
friend bool operator <= (const File&, const File&);
friend bool operator < (const File&, const File&);
friend bool operator > (const File&, const File&);
friend std::istream & operator >> (std::istream&, File&);
friend std::ostream & operator << (std::ostream&, File);
};
和我的operator()是这样的:
int File::operator () (char* contentNextNBytes, int n)
{
int i; int j = 0;
std::vector<char>::const_iterator it = content.begin();
for(j = 0; j < *indexOfCurrentChar; j++)
++it;
for(i = 0; i < n; i++)
{
contentNextNBytes[i] = *it;
if(i == *indexOfLastChar-1)
{
contentNextNBytes[i+1] = '\0';
*indexOfCurrentChar = i+1;
return i+1;
}
++it;
}
contentNextNBytes[i] = '\0';
*indexOfCurrentChar = n;
return n;
}
在我的另一个类Interface中,我用int i = dir[index](buffer, n)
调用operator(),其中n是字节数,index是目录中File的索引。
现在,正如在运算符中实现的那样,值* indexOfCurrentChar指向应该(并且确实)成为从File中提取的最后一个字符的位置。然而,当我再次使用int j = dir[index](buffer, n1)
调用相同的运算符时,正好当程序进入运算符{}时,它会再次将* indexOfCurrentChar的值更改为0,而我的代码应该从最后一个char继续并读取文件
为什么会这样? :(
这是我用来在类Interface中调用运算符的代码的一部分:
buffer = new char[n+1];
k = d[index](buffer, n);
std::cout<<"Extracting of "<<k<<" bytes succeeded, and here is the content extracted:\n";
std::cout<<"\""<<buffer<<"\"";
Edit1:这是我改变indexOfCurrentChar的地方:
1)在赋值运算符=(但是,我没有在我的Interface类中调用它) 2)在复制构造函数中(也没有在Interface类中使用它,它只复制值) 3)在File构造函数中:
File::File()
{
// stuff
indexOfCurrentChar = new int;
} //I'm not setting its value, just allocating memory
4)在File构造函数中:
File::File(std::string arg_name, int arg_size, std::string arg_content)
{
// stuff
indexOfCurrentChar = new int;
*indexOfCurrentChar = 0;
//setting it to 0, but its just at creation time
}
5)在&gt;&gt;操作者 //获取文件内容
std::cout<<"Enter file content: ";
*object.indexOfCurrentChar = 0;
while( in.get(c) && c != '\n');
i = 0;
in.get(c);
if(*(object.pSize) == 0)
{
while(c != '\n')
{
object.content.push_back(c);
in.get(c);
++i;
}
*(object.pSize) = (int)object.content.size();
*(object.pPosOfEnd) = object.content.end();
*object.indexOfLastChar = i;
}
else
{
i = 0;
std::vector<char>::const_iterator it = object.content.begin();
while(c != '\n')
{
if(i == *object.pSize)
{
*object.pPosOfEnd = it;
*object.indexOfLastChar = i;
}
if(i >= *object.pSize)
{
in.get(c);
continue;
}
object.content.push_back(c);
in.get(c);
++i;
}
}
*(object.pPos) = object.content.begin();
就是这样:))
Aaaaand虽然我很遗憾向全世界展示这个,但这是我丑陋的Interface类方法。我的所有程序输入/输出都是通过Interface.writeOutput方法管理的,它位于:
Interface::Interface()
{
menu = new char*[12];
menu[0] = "Welcome, please select an option from the following, by pressing the respective numbers:";
menu[1] = "1 Create a Directory\n2 Create a single File\n3 Exit program";
menu[2] = "Ok, now please select a further option:";
menu[3] = "Enter the number of Files you want to import: ";
menu[4] = "Enter the files...";
menu[5] = "1 Write out the Directory details\n2 Extract N bytes from a desired file\n3 Remove a file with desired name from the Directory\n4 Write content of a file\n0 Go back to the beginning";
menu[6] = "Enter the index of the file: ";
menu[7] = "Enter how many bytes to extract: ";
menu[8] = "Content of the extracted bytes: ";
menu[9] = "Enter the name of the file: ";
menu[10] = "What do you want to do next?";
menu[11] = "Please enter a regular number...";
}
void Interface::writeMenu()
{
Error e;
char c, tmp[5], name[30];
int n, k, index, i, numDir;
char *buffer;
int *haveReadFiles;
std::cout<<menu[0];
std::cout<<"\n\n";
startMenu:
std::cout<<menu[1];
std::cout<<"\n\n";
std::cin>>c;
if((!isdigit(c)) || ( c != '1' && c!= '2' && c!='3'))
{
std::cout<<"\n"<<menu[11]<<"\n\n";
goto startMenu;
}
if(c == '1')
{
std::cout<<"Enter the name of the directory: ";
std::cin>>name;
Directory d(name);
std::cout<<"\n\n\nEnter number of files of directory: ";
std::cin>>numDir;
haveReadFiles = new int[numDir];
if(!haveReadFiles)
{
e.writeToOutput(7);
exit(1);
}
for(i = 0; i < numDir; i++)
{
haveReadFiles[i] = 0;
//std::cin.ignore(5,'\n');
// std::cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
File f;
std::cin>>f;
d += f;
}
menu1:
std::cout<<"\n\n"<<menu[2]<<"\n\n";
menuRepeat:
std::cout<<menu[5];
std::cout<<"\n\n";
std::cin>>c;
if(!isdigit(c) || (c != '1' && c!= '2' && c!='3' && c != '4' && c != '0'))
{
std::cout<<"\n"<<menu[11];
goto menu1;
}
switch(c)
{
case '0': goto startMenu;break;
case '1': std::cout<<d;break;
case '2':
{
menu2:
std::cout<<"\n\n"<<menu[6];
std::cin>>tmp;
for(i = 0; i < (int)strlen(tmp); i++)
if(!isdigit(tmp[i]))
{
std::cout<<"\n\n"<<menu[11];
goto menu2;
}
index = atoi(tmp);
menu3:
std::cout<<"\n\n"<<menu[7];
std::cin>>tmp;
for(i = 0; i < (int)strlen(tmp); i++)
if(!isdigit(tmp[i]))
{
std::cout<<"\n\n"<<menu[11];
goto menu3;
}
n = atoi(tmp);
buffer = new char[n+1];
k = d[index](buffer, n);
std::cout<<"Extracting of "<<k<<" bytes succeeded, and here is the content extracted:\n";
std::cout<<"\""<<buffer<<"\"";
} break;
case '3':
{
std::cout<<"\n\nEnter the name of the file: ";
std::cin>>name;
d -= name;
std::cout<<"...file removed!\n";
std::cout<<"Directory without the removed file looks like this: \n\n"<<d;
}break;
case '4':
{
menuFF:
std::cout<<"\n\nEnter the index of the desired file: ";
std::cin>>tmp;
for(i = 0; i < (int)strlen(tmp); i++)
if(!isdigit(tmp[i]))
{
std::cout<<"\n\n"<<menu[11];
goto menuFF;
}
index = atoi(tmp);
std::cout<<"\nHere's the content:\n";
File ff = d[index];
std::vector<char>::const_iterator iter = ff.content.begin();
for(; iter < ff.content.end(); ++iter)
{
std::cout<<*iter;
}
std::cout<<"\n\n";
}
}
menu4:
std::cout<<"\n\nWhat do you want to do now?\n\n1 Exit program\n2 Go back to start menu\n3 Do more stuff with your Directory\n\n";
std::cin>>c;
if((!isdigit(c)) || ( c != '1' && c!= '2' && c!='3'))
{
std::cout<<"\n"<<menu[11];
goto menu4;
}
if(c=='1')
{
"Thank you, goodbye...";
exit(0);
}
if(c=='2')
goto startMenu;
if(c=='3')
goto menuRepeat;
}
else if(c=='2')
{
std::cout<<"Enter your file...\n";
File g;
std::cin>>g;
menuZZ:
std::cout<<"\n\nHere's what you can do with your file: \n\n1 Extract N bytes of content from it\n2 Write its content out\n3 Write its properties out\n4 Return to start menu\n\n";
std::cin>>c;
switch(c)
{
case '1':
{
menuYY:
std::cout<<"\n\n"<<menu[7];
std::cin>>tmp;
for(i = 0; i < (int)strlen(tmp); i++)
if(!isdigit(tmp[i]))
{
std::cout<<"\n\n"<<menu[11];
goto menuYY;
}
n = atoi(tmp);
buffer = new char[n+1];
k = g(buffer, n);
std::cout<<"Extracting of "<<k<<" bytes succeeded, and here is the content extracted:\n";
std::cout<<"\""<<buffer<<"\"";
std::cout<<"\n\n";
goto startMenu;
} break;
case'2':
{
std::vector<char>::const_iterator it = g.content.begin();
for(; it < g.content.end(); ++it)
{
std::cout<<*it;
}
std::cout<<"\n\n";
}
case'3':
{
std::cout<<g<<"\n\n";
goto startMenu;
} break;
case'4':
{
std::cout<<"\n\n";
goto startMenu;
} break;
default:
{
std::cout<<menu[11];
goto menuZZ;
}
}
}
else
{
std::cout<<"Thank you, goodbye... ";
exit(0);
}
}
编辑2:
最后但并非最不重要的是Directory::operator [] implementation
:
标题:File& operator [] (int);
实施:
File& Directory::operator [] (int index)
{
std::vector<File>::const_iterator i = arr.begin();
for(int j = 0; j < index; ++j)
++i;
File* temp = new File;
*temp = *i;
return *temp;
delete temp;
}
享受^^
答案 0 :(得分:2)
我的猜测是问题在于Directory
类以及它存储和返回File
个对象的方式。例如,如果Directory::operator[]
返回File
而不是File &
,那么对返回的对象所做的任何更改都不会保留到Directory
的内部副本,所以连续两次打电话,如
int i = dir[index](buffer, n);
int j = dir[index](buffer, n1);
实际上导致在两个不同的临时File::operator()
对象上调用File
。这可以解释为什么*indexOfCurrentChar
的值不是您所期望的。
修改强>
既然你已经展示了Directory::operator[]
的实现,我可以自信地说我的怀疑是正确的。即使您更改了Directory::operator[]
的签名以便它现在返回File &
,您的实现仍然不会按照您希望的方式运行,因为它不会返回对正确{{1}的引用。 1}} object(File
对象的内部副本)。三个陈述
Directory
创建File* temp = new File;
*temp = *i;
return *temp;
对象的内部Directory
对象的新副本并返回对该对象的引用,因此对返回的File
对象的成员变量所做的任何更改都不会反映在File
向量的相应条目。由于Directory::arr
会返回引用,因此将vector::operator[]
的正文更改为
Directory::operator[]
应该给你想要的行为。
我可能还应该注意到,return arr[index];
泄漏内存的当前实现:Directory::operator[]
永远不会运行,因为delete temp;
导致控件离开函数。
答案 1 :(得分:0)
我建议更换
if(i == *indexOfLastChar-1)
与
if(i == (*indexOfLastChar)-1)
我认为你正在读取'indexOf Last Char'之前的值并将其与i进行比较。
答案 2 :(得分:0)
我发布了这个作为评论,但我认为
indexOfCurrentChar = n;
应该是
*indexOfCurrentChar += n;