是否有一个版本的sscanf()不能从第一个字节开始?

时间:2016-12-21 22:42:30

标签: c

在C中,fscanf()不一定从第一个字节读取文件;它从当前的访问位置读取文件。我需要一个sscanf()版本,它对字符串做同样的事情。是否有任何功能(标准或非标准)用于此目的?

更新:似乎我没有很好地提出这个问题。我不知道这种sscanf()应该开始读取的地点/偏移的数值;我想让它从之前调用它的地方读完。感谢。

4 个答案:

答案 0 :(得分:7)

在简单的情况下,您可以使用"%n"说明符,例如

int x, y, length;
if (sscanf(string, "%d%d%n", &x, &y, &length) == 2) ...

现在length将“位置”放入字符串中,以便下次可以从那里继续

if (sscanf(string + length, "%d%d%n", &x, &y, &length) == 2) ...

在更复杂的情况下,您可能需要的不仅仅是sscanf(),或者取决于您所在的平台fmemopen(3),因此您可以使用fscanf()同时拥有您希望的字符串并与之交互,就好像它是一个文件一样。

答案 1 :(得分:0)

  

为此目的是否有任何功能(标准或非标准)?

不,没有。您必须跟踪从字符串中偏移的数量,并在调用sscanf时使用它。

sscanf(string + offset, ...);

要跟踪偏移量,您可以使用%n格式说明符让sscanf告诉您消耗的字符数。

int offset = 0;
int n = 0;
sscanf(string + offset, "....%n", ... &n);
offset += n;

...

sscanf(string + offset, "....%n", ... &n);
offset += n;

答案 2 :(得分:0)

C字符串没有当前访问位置的概念,除非您在外部提供。因此,sscanf()的任何变体都不能将固有的当前访问位置考虑在内。原则上,可能有一个变量接受起始位置作为附加参数,但这将是多余的,因为正如@MichaelWalz所观察到的,您可以使用常规指针算法来实现sscanf()本身。

答案 3 :(得分:0)

使用try: db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db" db = dataset.connect(db_path) self.table = db[table_name].table except Exception: traceback.exec_print() 是处理扫描字符串的常用方法,因为"%n记录了扫描到该点的偏移量。

将其附加到格式的末尾并测试索引值是否从-1更改。这适用于简单和复杂的格式。

"%n"

输出

int scanf_buffer_2_step(const char * buffer) {
  int i;
  double d;

  // Initialize to a value that a successful scan would never use.
  int n = -1;

  // append                vv       vv
  sscanf(buffer, "Index:%d,%n", &i, &n);

  // Test for success
  if (n < 0) return 1; // fail

  // Advance pointer to next string position
  buffer += n; 

  // Do it some more    
  n = -1;
  sscanf(buffer, " Data:%lf End of the line %n", &d, &n);
  if (n < 0) return 1; // fail
  buffer += n; // Advance pointer to next string position

  if (buffer[0] != '\0') return 1; // fail (extra data)

  printf("(%i %f)", i, d);
  return 0;
}

int main(void) {
  printf("%d\n", scanf_buffer_2_step("Index:1, Data:123.456 End of the line"));
  printf("%d\n", scanf_buffer_2_step("Index:1, Data:123.456 End of the line extra"));
  printf("%d\n", scanf_buffer_2_step("Index:1,"));
  return 0;
}

对于最终扫描,如果在字符串末尾允许使用(1 123.456000)0 1 1 这样的空格,请考虑附加" %n"

对于'\n',还会出现问题,例如检查fscanf()的返回值。