繁体   English   中英

fscanf 解析数据(格式说明符)C++

[英]fscanf parse data (format specifier) C++

我有一个这样的结构:

struct Office {
char city[50];
int employees;
char desc[200];
}

struct Office office[100];

然后我想在一个循环中填充办公室数组,直到到达文件末尾。

这是我的数据:

Toronto
    151: This is HQ

Vancouver
    23: This is branch office

London
    12: This is euro branch

以此为例:

Toronto
    151: This is HQ

所以在这里我想将其解析为结构:

city = "Toronto"
employees = 151
desc = "This is HQ"

注意:在员工人数前的新行中的城市名称后,有TAB(4个空格)

我有一个这样的实现,但似乎它不能正常工作:

int function LoadOffices(const char *f) {
  int res = 1;
  char buf[500];
  char city[50];
  int emp;
  char desc[200];
  struct Office offices[100];
  FILE *fp = fopen(f, "r");

  if (fp) {
    while (fgets(buf, sizeof(line), fp) != nullptr) {
      if (i == 0) {
        rewind(fp);
      }
      i++;
      if (fscanf(fp, "%[^\n]", city) == 1) {
        strncpy(offices[i].city, city, 50);
      } else if (fscanf(fp, "%d[^:]:%[^\n]", &emp, desc) == 2) {
        offices[i].employees = emp;
        strncpy(offices[i].desc, desc, 200);
      }
    }
    res = 0;
  } else {
    res = 1;
  }

  fclose(fp);
  return res;
}

我只想知道如何处理 TAB 和空行

程序的结构对解决问题的难易程度有很大的影响。

要加载任何类型的struct数组,您应该使用一个习惯用法:

  • 制作一个读取单个struct的 function
  • 有办法确定function上的那个function成败在stream上
  • 制作另一个 function 使用第一个来读取该struct的数组/列表/任何内容

以下是我建议您进行的工作:

bool LoadAnOffice( FILE * fp, struct Office * office );
// Attempt to read a single office from the open stream 'fp'
// Returns success or failure

bool LoadOffices( FILE * fp, struct Office offices[], size_t * num_offices, size_t max_num_offices );
// Fill an array of offices by loading them from the open stream 'fp'
// Returns the number of offices loaded in '*num_offices'
// Reads at most 'max_num_offices'
// Returns 'true' if EOF encountered, 'false' otherwise

你甚至可以添加一个 function 通过打开一个文件来实现它:

bool LoadOfficesFromFile( const char * filename, struct Office offices[], size_t * num_offices, size_t max_num_offices )
{
  FILE * f = fopen( filename, "r" );
  if (!f) return false;
  bool result = LoadOffices( f, offices, num_offices, max_num_offices );
  fclose( f );
  return result;
}

此后,您的程序可以轻松处理从文件中加载您的办公室:

int main(void)
{
  #define MAX_OFFICES 100
  struct Office offices[MAX_OFFICES];
  size_t n_offices = 0;

  if (!LoadOfficesFromFile( "offices.txt", offices, &n_offices, MAX_OFFICES ))
  {
    fprintf( stderr, "%s\n", "complain!" );
    ...
  }

不短,但它是模块化处理结构化类型的文件 I/O 的好方法。 你会发现自己一遍又一遍地使用这个习语的一些变体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM