C++ C++;测试文件生成器生成不一致的数据

C++ C++;测试文件生成器生成不一致的数据,c++,C++,假设该程序根据用户提供的参数生成测试文件。该文件模拟具有第一个参数fileNumber的命令。例如: START 1 WRITE 1 1 WRITE 1 1 READ 1 1 START 2 READ 1 1 ... ... READ 2 1 END 1 WRITE 1 2 WRITE 1 2 READ 2 2 WRITE 1 1 WRITE 1 2 WRITE 1 2 WRITE 2 3 WRITE 2 4 WRITE 2 5 END 2 问题是结束文件号之后的行不应再对该文件号执行任何操作

假设该程序根据用户提供的参数生成测试文件。该文件模拟具有第一个参数fileNumber的命令。例如:

START 1
WRITE 1 1
WRITE 1 1
READ 1 1
START 2
READ 1 1
...
...
READ 2 1
END 1
WRITE 1 2
WRITE 1 2
READ 2 2
WRITE 1 1
WRITE 1 2
WRITE 1 2
WRITE 2 3
WRITE 2 4
WRITE 2 5
END 2
问题是
结束文件号
之后的行不应再对该文件号执行任何操作

上面的示例文本文件是由生成器生成的,并演示了问题:在第
行结束1
之后,仍然有多个
写入1*

代码如下:

  int main(int argc, char **argv){
  if(argc < 4){
      usage(argv[0]);
      exit(EXIT_FAILURE);
  }

  // extract command line arguments
  std::stringstream ss;
  int diskCapacity = atoi(argv[1]);// ss << argv[1]; ss >> diskCapacity;
  int writeRatio = atoi(argv[2]);// ss << argv[2]; ss >> writeRatio;
  char *ofileName = argv[3];

  // validate writeRatio
  if( (writeRatio < 0) || (writeRatio > 100) ) {
      std::cerr << argv[0] << ": writeRatio out of range [0,100]: " << writeRatio << std::endl;
      exit(EXIT_FAILURE);
  }

  std::ofstream outfile;
  outfile.open(ofileName);

  // seed rng
  std::chrono::high_resolution_clock::time_point time = std::chrono::high_resolution_clock::now();
  std::minstd_rand rng(time.time_since_epoch().count());

  /***** generate simluation sequence *****/
  int diskSize = 0;
  std::vector<File> aliveFiles;
  int new_fid = 1;
  int nFilesCreated = 0;

  // create at least 1 file
  File f;
  f.id = new_fid++;
  f.size = 1;
  aliveFiles.push_back(f);
  diskSize++;
  nFilesCreated++;
  outfile << start(f.id) << std::endl;

  do {
      // start
      if( ((rng()%10) < 2) && (nFilesCreated < diskCapacity/4) ){
        // new file
        f.id = new_fid++;
        f.size = 1;

        // add to disk
        aliveFiles.push_back(f);
        diskSize++;
        nFilesCreated++;
        outfile << start(f.id) << std::endl;
        continue;
    }

    // choose a file
    int new_fsize = -1;
    int new_fid = -1;
    if(!aliveFiles.empty()) {
        std::random_shuffle(aliveFiles.begin(), aliveFiles.end());
        new_fid = (aliveFiles.back()).id;
        new_fsize = (aliveFiles.back()).size;
    }
    else {
        break;
    }
    // write
    if( (int)(rng() % 100) < writeRatio ) {
        // writeRatio% chance to write
        int block = 1 + (rng() % new_fsize);
        File newFile;
        if(block == new_fsize) {
            // writing new block
            diskSize++;
            new_fsize++;
            newFile.id = new_fid;
            newFile.size = new_fsize;
            aliveFiles.pop_back();
            aliveFiles.push_back(newFile);
        }
        outfile << write(newFile.id, block) << std::endl;
        continue;
    }

    // end/read
    if(rng() % 100 == 0) {
        // end
        aliveFiles.pop_back();
        outfile << end(new_fid) << std::endl;
    }
    else {
        if( (int)(rng() % 100) < (100-writeRatio) ){
            // (100-writeRatio)% chance to read
            if(new_fsize > 1) {
                int block = 1 + (rng() % (new_fsize-1));
                outfile << read(new_fid, block) << std::endl;
            }
        }
    }
  } while(diskSize < diskCapacity);

  // check that all files have ended, if not then clean up
  while(!aliveFiles.empty()) {
      new_fid = (aliveFiles.back()).id;
      aliveFiles.pop_back();
      outfile << end(new_fid) << std::endl;
  }

  return 0;
}
int main(int argc,char**argv){
如果(argc<4){
用法(argv[0]);
退出(退出失败);
}
//提取命令行参数
std::stringstream-ss;
int diskCapacity=atoi(argv[1]);//ss>diskCapacity;
int writeRatio=atoi(argv[2]);//ss>writeRatio;
char*ofileName=argv[3];
//验证写入
如果((写操作<0)| |(写操作>100)){

std::cerr错误相当严重。如果查看测试数据,您会注意到错误的文件号只出现在
写入
行中,而不会出现在
读取
行中

这将问题缩小到代码的这一部分,即使用变量
newFile
,而不首先初始化它:

    // write
    if((int)(rng() % 100) < writeRatio) {
        // writeRatio% chance to write
        int block = 1 + (rng() % new_fsize);
        File newFile;                     //  <===== unitialized !!
        if(block == new_fsize) {          //  <===== what happens if this is false ?   
            // writing new block
            diskSize++;
            new_fsize++;
            newFile.id = new_fid;
            newFile.size = new_fsize;
            aliveFiles.pop_back();
            aliveFiles.push_back(newFile);
        }
    outfile << write(newFile.id, block) << std::endl; // <== OUCH, if the if condition failed you go here with random data in newFile !!   
        continue;
    }
//写
如果((int)(rng()%100)File newFile;//捕捉得很好。我花了一整晚都没找到这个bug。@firefly注意新的_fid变量。它定义了两次,一次在do/while之外,一次在do/while中。可能不是你想要的。@user4581301这也是一个非常好的拍摄方法!恭喜!而且非常糟糕:循环体的第一部分指循环外的新fid,但循环的第二部分会被重新定义。你可能在另一个晚上救了firefly。它可能会做OP希望它做的事情,因为内部新fid在程序使用外部新fid完成之前不应该被推到堆栈上,但是如果出现了一些漂亮的优化,上帝会帮助他或她编译器中的ck有一个更好的想法。