Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将记录写入.dat文件C++; 我对C++非常陌生,我正在尝试解决如何将这个结构的记录写入到一个文本文件: struct user { int id; char username [20]; char password [20]; char name [20]; char email [30]; int telephone; char address [70]; int level; };_C++_File Io_Record - Fatal编程技术网

将记录写入.dat文件C++; 我对C++非常陌生,我正在尝试解决如何将这个结构的记录写入到一个文本文件: struct user { int id; char username [20]; char password [20]; char name [20]; char email [30]; int telephone; char address [70]; int level; };

将记录写入.dat文件C++; 我对C++非常陌生,我正在尝试解决如何将这个结构的记录写入到一个文本文件: struct user { int id; char username [20]; char password [20]; char name [20]; char email [30]; int telephone; char address [70]; int level; };,c++,file-io,record,C++,File Io,Record,到目前为止,我可以很好地写入它,但没有递增的id号,因为我不知道如何计算记录数,所以在我将数据写入文件后,文件看起来是这样的 1 Nick pass Nick email tele address 1 1 user pass name email tele address 1 1 test test test test test test 1 1 user pass Nick email tele addy 1 1 nbao pass Nick email tele 207 1 使用以下代码:

到目前为止,我可以很好地写入它,但没有递增的id号,因为我不知道如何计算记录数,所以在我将数据写入文件后,文件看起来是这样的

1 Nick pass Nick email tele address 1
1 user pass name email tele address 1
1 test test test test test test 1
1 user pass Nick email tele addy 1
1 nbao pass Nick email tele 207 1
使用以下代码:

ofstream outFile;

outFile.open("users.dat", ios::app);

// User input of data here

outFile << "\n" << 1 << " " << username << " " << password << " " << name << " "
        << email << " " << telephone << " " << address  << " " << 1;
cout << "\nUser added successfully\n\n";

outFile.close();
流出管的
;
outFile.open(“users.dat”,ios::app);
//用户在此输入数据

outFileA.Dat文件本身通常是一个简单的文本文件,可以用记事本打开。因此,您可以简单地读取文件的最后一行,读取它,提取第一个字符,将其转换为整数。然后增加该值并完成。 这里有一些示例代码:

  #include <iostream.h>
  #include <fstream.h>
  using namespace std;

  int main(int argc, char *argv[])
  {
    ifstream in("test.txt");

  if(!in) {
       cout << "Cannot open input file.\n";
       return 1;
    }

     char str[255];

     while(in) {
       in.getline(str, 255);  // delim defaults to '\n'
        //if(in) cout << str << endl;
     }
    // Now str contains the last line , 
    if  ((str[0] >=48) || ( str[0] <=57))
    {
      int i = atoi(str[0]);
      i++;
    } 
    //i contains the latest value , do your operation now
    in.close();

     return 0;
     }
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[])
{
ifstream-in(“test.txt”);
如果(!in){

cout假设您的文件格式不需要是人类可读的

您可以将结构写入文件,例如

outFile.open("users.dat", ios::app | ios::binary);
user someValue = {};
outFile.write( (char*)&someValue, sizeof(user) );

int nIndex = 0;
user fetchValue = {};
ifstream inputFile.open("user.data", ios::binary);

inputFile.seekg (0, ios::end);

int itemCount = inputFile.tellg() / sizeof(user);

inputFile.seekg (0, ios::beg);

if( nIndex > -1 && nIndex < itemCount){
    inputFile.seekg ( sizeof(user) * nIndex , ios::beg);
    inputFile.read( (char*)&fetchValue, sizeof(user) );
}
outFile.open(“users.dat”,ios::app | ios::binary);
用户someValue={};
write((char*)&someValue,sizeof(user));
int-nIndex=0;
用户fetchValue={};
ifstream inputFile.open(“user.data”,ios::binary);
inputFile.seekg(0,ios::end);
int itemCount=inputFile.tellg()/sizeof(用户);
inputFile.seekg(0,ios::beg);
如果(nIndex>-1&&nIndex
写入文件的代码是用户结构的成员函数? 否则,我看不到输出和结构之间的连接

可能要做的事情:

  • 写入id成员而不是1
  • 对id使用计数器,并在每次写入时递增
  • 不要写id,读取时使用行号作为id

使用典型方法,如果您想在读取文件时进行随机访问,至少需要使用固定大小的记录,因此,假设您有5个字符作为名称,文件将存储为

bob\0\0
或者使用任何其他方法填充,这样您就可以使用记录编号*记录大小进行索引

要以您正在执行的方式增加索引,您需要读取文件以查找高现有索引并增加它。或者,您可以将文件加载到内存中,附加新记录并将文件写回

std::vector<user> users=read_dat("file.dat");
user user_=get_from_input();
users.push_back(user_);

then write the file back
std::ofstream file("file.dat");
for(size_t i=0; i!=users.size(); ++i) {
    file << users.at(i); 
   //you will need to implement the stream extractor to do this easily
}
std::vector users=read_dat(“file.dat”);
用户=从输入获取输入();
用户。推回(用户);
然后写回文件
std::of流文件(“file.dat”);
对于(size_t i=0;i!=users.size();++i){

file到目前为止,您拥有的还不错,只是它不能处理字符串中有空格的情况(例如在address中!)

您要做的是编写一个非常基本的数据库。您需要三个需要单独实现的操作(尽管在某些情况下,将它们交织在一起可能会提供更好的性能,但我相信这不是您关心的问题)

  • Insert:您已经实现了此操作。您可能只想将
    更改为
    ”\n“
    。这样,结构的每个字段都位于新行中,您的空格问题就得到了解决。以后阅读时,您需要逐行阅读
  • 搜索:要搜索,您需要打开文件,逐结构读取结构(它本身包括读取与您的结构字段对应的许多行)并识别您感兴趣的实体。如何处理它们是另一个问题,但最简单的情况是返回数组(或向量)中匹配实体的列表
  • 删除:这与搜索类似,只是您必须重写文件。您所做的基本上是,逐个结构读取,查看哪些符合您的删除条件。忽略那些匹配的,然后将其余部分(如插入部分)写入另一个文件。然后,您可以用新文件替换原始文件
下面是一个伪代码:

Write-entity(user &u, ofstream &fout)
    fout << u.id << endl
         << u.username << endl
         << u.password << endl
         << ...

Read-entity(user &u, ifstream &fin)
     char ignore_new_line
     fin >> u.id >> ignore_new_line
     fin.getline(u.username, 20);
     fin.getline(u.password, 20);
     ...
     if end of file
         return fail

Insert(user &u)
     ofstream fout("db.dat");
     Write-entity(u, fout);
     fout.close();

Search(char *username) /* for example */
     ifstream fin("db.dat");
     user u;
     vector<user> results;
     while (Read-entity(u))
         if (strcmp(username, u.username) == 0)
             results.push_back(u);
     fin.close();
     return results;

Delete(int level) /* for example */
     ifstream fin("db.dat");
     ofstream fout("db_temp.dat");
     user u;
     while (Read-entity(u))
         if (level != u.level)
             Write-entity(u, fout);
     fin.close();
     fout.close();
     copy "db_temp.dat" to "db.dat"
写入实体(用户和u、流和流)

fout我建议将文件处理程序包装到一个类中,然后重载操作符
>,文件是否需要纯文本?您的格式是否允许删除对象?使用
std::string
而不是C-style
char*
字符串,省略
@Walter,使用C-style
char*
也会自动删除s空白。此外,
@Nico在我可以选择一条记录之后,我将实现编辑和删除记录的功能。如果用户名/密码/姓名/电子邮件/地址包含空格字符,事情将开始破裂。+1用于创建
用户
类型。但是不需要
MyDataFile
(事实上,我会认为这是坏的,因为您现在不能从STD::STRIGSTROW(或其他流)读取<代码>用户<代码>。您可以编写一个自由函数来从流中读取用户:<代码> STD::ISTRAMAM和运算符>(STD::ISTRAMAM和SUSTER,用户和数据){/*THOST*/}。
std::ostream&operator+1,因为您引入了
用户
类的概念。但它掩盖了太多的问题。如果任何字符串短于其最大值(通常都是这样),也会断开它可能会中断,如果你有太多的空间,并没有覆盖错误处理足够。“LokiAstari,我故意掩盖了这些问题。首先,我不打算写整个程序在这里,只是基本的想法。第二,OP是真正的新的C++,我相信杂乱的算法与一批错误检查将在我把他搞糊涂了。最后,这种编写数据库的方式很糟糕,只适合一个简单的练习程序。我在op的结构中没有看到任何指针。也许我看得太多了?
Write-entity(user &u, ofstream &fout)
    fout << u.id << endl
         << u.username << endl
         << u.password << endl
         << ...

Read-entity(user &u, ifstream &fin)
     char ignore_new_line
     fin >> u.id >> ignore_new_line
     fin.getline(u.username, 20);
     fin.getline(u.password, 20);
     ...
     if end of file
         return fail

Insert(user &u)
     ofstream fout("db.dat");
     Write-entity(u, fout);
     fout.close();

Search(char *username) /* for example */
     ifstream fin("db.dat");
     user u;
     vector<user> results;
     while (Read-entity(u))
         if (strcmp(username, u.username) == 0)
             results.push_back(u);
     fin.close();
     return results;

Delete(int level) /* for example */
     ifstream fin("db.dat");
     ofstream fout("db_temp.dat");
     user u;
     while (Read-entity(u))
         if (level != u.level)
             Write-entity(u, fout);
     fin.close();
     fout.close();
     copy "db_temp.dat" to "db.dat"
struct User{
...
};

typedef std::vector<User> UserConT;

struct MyDataFile
{
  ofstream outFile;
  UserConT User_container;

  MyDataFile(std::string const&); //
  MyDataFile& operator<< (User const& user); // Implement and/or process the record before to write
  MyDataFile& operator>> (UserConT & user); // Implement the extraction/parse and insert into container
  MyDataFile& operator<< (UserConT const & user); //Implement extraction/parse and insert into ofstream 
};

MyDataFile& MyDataFile::operator<< (User const& user)
{
  static unsigned myIdRecord=User_container.size();
  myIdRecord++;
  outFile << user.id+myIdRecord << ....;
  return *this;
}



int main()
{
   MydataFile file("data.dat");

   UserConT myUser;
   User a;
   //... you could manage a single record  
   a.name="pepe"; 
   ...
   file<<a;
   ..//

}