【问题标题】:How to count amount of elements on each line of a file如何计算文件每一行的元素数量
【发布时间】:2016-03-22 01:59:21
【问题描述】:

我试图从一个文件中读取一些数据(最终读入一个结构,但现在并不重要)并确保该文件在每一行上具有相同数量的数据。每一行都可以有单词或数字,所以我将文件的一行转换为一个大字符串。然后,我尝试使用 strtok 和逗号(分隔数据)作为分隔符将此字符串拆分为标记。但是我如何计算逗号之间存在的令牌数量。 我试图计算每行逗号的数量,但由于某种原因,它的行为不像我期望的那样。文件中每一行有5条数据,全部用逗号分隔,所以每行应该有4个逗号。

 while (fgets(string, sizeof(string), f)) {
    input = fgetc(f);
        if(input == ','){
            i++;        
        }
        else if (input == ' '){
            printf("Error");
            exit(0);
        }
   }

    if(i % 4 != 0){
        printf("Error");
        exit(0);
    }   

在这里我试图计算每一行上的逗号数量(如果文件行上有空格,它应该显示错误,因为我只想要逗号分隔数据)。最后在 fgets 停止读取之后,我想看看“i”变量是否是 4 的倍数。我确信有一种更有效且用户友好的方法可以做到这一点,但我想不出一个。

谢谢!

【问题讨论】:

  • fgets(string, sizeof(string), f)读入string的数据没有被使用。这是你的意图吗?
  • 你为什么同时使用fgets() fgetc()
  • 计算一行中的逗号并在空格中中止的一种简单方法是遍历该行,类似于:size_t commaCount=0; for( size_t i=0; string[i]; i++) { if( ',' == string[i] ) { commaCount++; } else if( ' ' == string[i] ) { //abort due to space } }
  • 他的功能: fgets() 仅在换行符或 EOF 处停止。或者输入缓冲区只有一个字节要填充(由第二个参数定义)。因此 fgets() 不会停在空格或逗号上(除非那是填充输入缓冲区的内容)。所以对 fgetc() 的调用(通常)是从输入文件的下一行获取第一个字符。可能不是你想要的。
  • @user3629249 ,我不喜欢您的建议的原因是因为例如一行可以有 5 个逗号,而下一行可能有 3 个。该算法将无法发现一行没有 4 个。

标签: c file fgets fgetc


【解决方案1】:

要计算文件每一行的逗号,您需要知道文件中的确切行分隔符。然后你可以遍历文件直到到达文件结尾并计算行内的逗号。

在以下示例中,我假设 '\n' 是行分隔符。

#define DESIRED_COMMAS_COUNT 4
int commas_per_line = 0;
bool prev_is_comma = false;
int c;
while ((c = fgetc(f)) != EOF) //This expression reads one characters from file and checks for end-of-file condition
{
  switch(c)
  {
    case ',': 
      commas_per_line++; 
      if (prev_is_comma)
      {
        printf("Two successive commas! Empty element in line\n");
        exit(1);
      }
      prev_is_comma = true;
      if (commas_per_line > DESIRED_COMMAS_COUNT)
      {
        printf("Error: too many commas at line. At least %d.\n", commas_per_line);
        exit(1);
      }
      break;
    case ' ': 
      printf("Error: space encountered!\n"); 
      exit(1);
    case '\n': 
      if (commas_per_line != DESIRED_COMMAS_COUNT)
      {
        printf("Error: too low commas (%d)", commas_per_line);
        exit(1);
      }
      if (prev_is_comma)
      {
        printf("Line ends with comma: no last element in line\n");
        exit(1);
      }
      commas_per_line = 0; 
      break;
    default:
      prev_is_comma = false;
  }
}
if ((commas_per_line != DESIRED_COMMAS_COUNT) && //check commas count for last line in file
    (commas_per_line != 0))
{
  printf("Error: too low commas (%d)", commas_per_line);
  exit(1);
}

【讨论】:

  • 1) 使用feof() 检查文件结尾是一个非常糟糕的主意,因为它不起作用,因为这个答案假设它起作用。 2) fgetc() 返回 int 而不是 char。 3) 建议:`int c; while( (c = fgetc()) != EOF )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 2021-06-12
相关资源
最近更新 更多