Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.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
C 将不需要的数据保存到错误文件_C_Function_Pointers_If Statement_Struct - Fatal编程技术网

C 将不需要的数据保存到错误文件

C 将不需要的数据保存到错误文件,c,function,pointers,if-statement,struct,C,Function,Pointers,If Statement,Struct,嗨,我现在有一段代码,从一个文件中获取名称,然后保存到另一个文件中 然而,我现在想将任何无效信息保存到一个固定的错误文件中,并且想知道我该怎么做 我的代码: 结构: struct Person{ char fName[16]; //string to store the persons first name char lName[21]; //string to store the persons last name }; 主要 打开记录计数(&recordCo

嗨,我现在有一段代码,从一个文件中获取名称,然后保存到另一个文件中

然而,我现在想将任何无效信息保存到一个固定的错误文件中,并且想知道我该怎么做

我的代码:

结构:

struct Person{
    char fName[16];     //string to store the persons first name
    char lName[21];     //string to store the persons last name
};
主要

打开记录计数(&recordCount),记录功能:

struct Person* open(int *rCount, struct Person *records){
  FILE *recordFile;
  char fileName[30] = {'\0'};
  int i = *rCount;
  char test;


  puts("Enter a filename to open :");
  scanf("%s", fileName);

  if((recordFile = fopen(fileName,"r"))==NULL){
      printf("Couldn't open the file: %s\n",fileName);
      exit(1);
  }
  else{

      test = fscanf(recordFile,"%s %s", records[i].fName,records[i].lName);
      while(test!= EOF){
          i++;
          records = realloc(records,(i+1)*sizeof(struct Person));
          test = fscanf(recordFile,"%s %s", records[i].fName,records[i].lName);
      }
      fclose(recordFile); // close the file
  }
  *rCount = i;
  return records;    //add i (records read from the file) to rCount (the current record count)
}
void errorLine(char *fileName)
{
FILE *errorFile;

  //try and open the file for writing and react accordingly if there is a problem
  if((errorFile = fopen("error.txt","w"))==NULL){
      printf("Couldn't open the file:\n");
  }
  else{ //the file opened so print the records array of Person's to it
      for(i=0;i<rCount;i++){
          fprintf(errorFile,"%i %s %s\n",records[i].fName,records[i].lName);
      }
      fclose(errorFile);   //close the file
      printf("Records saved to file: %s\n",fileName);
  }
}
添加记录和记录计数,记录功能

struct Person* addRecord(int* rCount, struct Person *records){

int valid = 0;  //used to indicated valid input
int length = 0; //used to store the string lengths
int i = 0;    //used in the for loops
char fNameTest[16];     //temporary storage of input to be checked before adding to records
char lNameTest[21];     //temporary storage of input to be checked before adding to records

//Checking the length of data input for fName
do{
    length = strlen(fNameTest);
    if(length < 16){
        for(i=0;i<=length;i++)                      
            records[*rCount].fName[i] = fNameTest[i]; //if correct insert the record at the index determined by rCount
        valid=1;
    }
    else{

        valid = 0;
    }

}while(valid!=1);

//Checking the length of data input for lName
do{
    length = strlen(lNameTest);
    if(length < 21){
        for(i=0;i<=length;i++)                    
            records[*rCount].lName[i] = lNameTest[i]; //if correct insert the record at the index determined by rCount
        valid=1;
        (*rCount)++;                                   //At this point ID,fName and lName have been stored so increment rCount
    }
    else{

        valid = 0;
    }

}while(valid!=1);


records = realloc(records,((*rCount)+1)*sizeof(struct Person));
return records;  //return rCount as the new updated recordCount
}
void save(int rCount, struct Person *records){
  FILE *recordFile;                 //file handle
  char fileName[30] = { '\0'};      //string to store the file name
  int i;

  puts("Enter a filename to save the records :");   //ask the user for the filename
  scanf("%s", fileName);                            //store the filename: data input should be checked
                                                    //here in your program

  //try and open the file for writing and react accordingly if there is a problem
  if((recordFile = fopen(fileName,"w"))==NULL){
      printf("Couldn't open the file: %s\n",fileName);
  }
  else{ //the file opened so print the records array of Person's to it
      for(i=0;i<rCount;i++){
          fprintf(recordFile,"%s %s\n",records[i].fName,records[i].lName);
      }
      fclose(recordFile);   //close the file
      printf("Records saved to file: %s\n",fileName);
  }

}
根据下面的答案编辑我已经更新了下面的代码编辑段

编辑保存函数

void save(int rCount, struct Person *records){
  FILE *recordFile;                 //file handle
  char fileName[30] = { '\0'};      //string to store the file name
  int i;

  puts("Enter a filename to save the records :");   //ask the user for the filename
  scanf("%s", fileName);                            //store the filename: data input should be checked
                                                    //here in your program

  //try and open the file for writing and react accordingly if there is a problem
  if((recordFile = fopen(fileName,"w"))==NULL){
      printf("Couldn't open the file: %s\n",fileName);
  }
  else{ //the file opened so print the records array of Person's to it

char fileName[sizeof (struct Person) * 2];  // twice needed size

while (fgets(fileName, sizeof fileName, recordFile) != NULL) {
struct Person P;

int n;  // Save index where scanning stopped
int cnt = sscanf(fileName,"%15s%21s %n", P.fName, P.lName, &n);
if (cnt != 2 || fileName[n]) {
  errorLine(fileName);
  // do not increment i;
} else {
  // Good to keep
  // realloc memory as needed here
  records[i] = P;
  i++;
  }

}
错误行功能:

struct Person* open(int *rCount, struct Person *records){
  FILE *recordFile;
  char fileName[30] = {'\0'};
  int i = *rCount;
  char test;


  puts("Enter a filename to open :");
  scanf("%s", fileName);

  if((recordFile = fopen(fileName,"r"))==NULL){
      printf("Couldn't open the file: %s\n",fileName);
      exit(1);
  }
  else{

      test = fscanf(recordFile,"%s %s", records[i].fName,records[i].lName);
      while(test!= EOF){
          i++;
          records = realloc(records,(i+1)*sizeof(struct Person));
          test = fscanf(recordFile,"%s %s", records[i].fName,records[i].lName);
      }
      fclose(recordFile); // close the file
  }
  *rCount = i;
  return records;    //add i (records read from the file) to rCount (the current record count)
}
void errorLine(char *fileName)
{
FILE *errorFile;

  //try and open the file for writing and react accordingly if there is a problem
  if((errorFile = fopen("error.txt","w"))==NULL){
      printf("Couldn't open the file:\n");
  }
  else{ //the file opened so print the records array of Person's to it
      for(i=0;i<rCount;i++){
          fprintf(errorFile,"%i %s %s\n",records[i].fName,records[i].lName);
      }
      fclose(errorFile);   //close the file
      printf("Records saved to file: %s\n",fileName);
  }
}

在我的程序最后一行中找到的

在试图保存到结构中之前,需要限制输入的长度

Bob Jones
Franklin Davies
James Donut
else {
  char buffer[sizeof (struct Person) * 2];  // twice needed size
  while (fgets(buffer, sizeof buffer, recordFile) != NULL) {
    struct Person P;

    int n;  // Save index where scanning stopped
    int cnt = sscanf(buffer,"%15s%21s %n", P.fName, P.lName, &n);
    if (cnt != 2 || buffer[n] || MaybeAddtionalTests(&P)) {
      SaveBadLine(buffer);
      // do not increment i;
    } else {
      // Good to keep
      // realloc memory as needed here
      records[i] = P;
      i++;
    }
  }
  fclose(recordFile); // close the file

抱歉,我对C有点陌生,但我认为您的答案是在save函数的else语句中实现的?还有几件事我不太明白,那就是MaybeaAdditionalTests和SaveBadLine是否有可能扩展我将要放在那里的内容?@Funkii Yes-在其他之后实现。由于%15s%21s的原因,名字和姓氏的长度当然受到限制。候选附加测试:检查字符串是否仅为字母。测试第一个字母是否大写,等等。对于坏记录,打开一个文件并将字符串附加到缓冲区中。这些只是代码的占位符函数。编辑了我的答案,感谢您进行了额外的测试,但正是出于这个目的,我不需要实现它们:不过毫无疑问,我可能把您的答案输入到我的代码中弄错了,再多的帮助也会有用great@Funkii见以上评论。可能需要记录=reallocrecords,i+1*sizeofstruct人员;替换注释//此处需要的realloc内存。重要的是,不仅要编辑代码,还要理解它。@Funkii原始代码和这个答案之间的区别是:原始代码在记录中添加了坏记录,然后试图测试它们。此答案在尝试将该行添加到记录之前测试该行,并且仅在其良好时添加该行。使用errorLinechar*fileName,而不是errorLinechar*fileName,const char*buf。。。。fopenerror.txt,一个。。。fprintferrorFile,%s\n,buf;a需要追加,而不是w需要重新编写。写入缓冲区,而不是不正确填充的记录[i]。没有循环。