如何在C中使用bool进行文件I/O?

yx2lnoni  于 2023-11-16  发布在  其他
关注(0)|答案(2)|浏览(182)

在执行文件I/O时,我应该像对待int一样对待bool变量吗?
我的意思是使用下面的代码片段是正确的吗?

bool b = true;
FILE *fp1, *fp2;
...
fprintf(fp1, "%d", b);
fscanf(fp2, "%d", &b);

字符串
我想知道基于ISO C规范的答案。

n3h0vuf2

n3h0vuf21#

在进行文件I/O时,我应该像对待int一样对待bool变量吗?
不,不是输入。
是的,可以用于输出,因为bool转换为int作为...参数的一部分,并且int匹配"%d"
我的意思是用...
不一定。它可能会工作。这是 * 未定义行为 *(UB)。
我想知道基于ISO C规范的答案。
没有C指定的方式通过fscanf()和朋友读取bool

  • bool缺少scanf()输入说明符。
  • bool的大小可能与int不同。它可能与char或其他相同。
  • 如果输入像"0""1"使用和"true""false"不需要,读入一个int并转换。
bool b = true;
FILE *fp1, *fp2;
...
fprintf(fp1, "%d", b);
int tmp;
fscanf(fp2, "%d", &tmp);
b = tmp;

字符串

  • 或者,使用字符串。
char tmp[2];
fscanf(fp2, "%1[0-1]", tmp);
b = tmp[0] == '1';

  • 接受"t""FalsE",.
  • 当然,应该检查scanf()的返回值。
  • 我会考虑一个helper函数:
Rough idea.  (Not really that great, just for illustration.)

// Read `bool` from `stdin`. Return 1 (success), EOF(end-of-file) and 0 in other cases.
int scan_bool(bool *b) {
  char buf[2];
  int cnt = scanf("%1[01tfTF]", buf);
  if (cnt != 1) {
    return cnt;
  }
  *b = buf[0] == '1' || buf[0] == 't' || buf[0] == 'T';
  return 1;
}

dsekswqp

dsekswqp2#

OP并不是在寻求一个替代方案,但下面的未经测试的 *1代码可以提供一些想法。它试图遵循fscanf()的精神,并接受“0”,“1”和无大小写的“t”,“f”,“true”,“false”。

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>

/* 
 * Read a 'bool'.
 * 
 * Read stream until:
 * * ignore leading white-space.
 * * a complete case-less match to: "0", "1", "f", "t", "false", "true",
 * * end-of-file, or input error.
 * Non-matching characters are pushed back.
 *
 * On success, assign *b as true or false (1 or 0).
 *
 * Return 1 on success,
 * EOF on input error or immediate end-of-file.
 * 0 otherwise.
 */
int fscan_bool(FILE *inf, bool *b) {
  int first_ch;
  do {
    first_ch = fgetc(inf);
  } while (isspace(first_ch));
  if (first_ch == '0' || first_ch == '1') {
    *b = (first_ch == '1');
    return 1;
  }
  if (first_ch == EOF) {
    return EOF;
  }
  int buf[5];
  buf[0] = first_ch;
  first_ch = tolower(first_ch);
  if (first_ch != 'f' && first_ch != 't') {
    ungetc(buf[0], inf);
    return 0;
  }

  bool value = (first_ch == 't');
  static const char *ft[2] = {"false", "true"};
  const char *match = ft[value];
  for (unsigned i = 1; match[i]; i++) {
    buf[i] = fgetc(inf);
    int next_ch = tolower(buf[i]);
    if ((next_ch == EOF) && !feof(inf)) { // Input error
      return EOF;
    }
    if (next_ch != match[i]) {
      do {
        // Attempt to unget all "next" characters.
        // The first attempt should work if not EOF.
        // Subsequent ones may work, may fail.
        ungetc(buf[i--], inf);
      } while (i > 0);
      break;
    }
  }
  *b = value;
  return 1;
}

字符串

  • 1原来彻底的测试是棘手的。

类似代码和测试线束here的代码评审请求。

相关问题