【问题标题】:sscanf doesn't move, scanning same integer everytimesscanf 不动,每次扫描相同的整数
【发布时间】:2012-06-05 07:37:48
【问题描述】:

我有一个包含整数的字符串,我正在尝试将所有整数放入另一个数组中。当sscanf 找不到int 时,我希望循环停止。所以,我做了以下事情:

int i;
int getout = 0;
for (i = 0; i < bsize && !getout; i++) {
    if (!sscanf(startbuffer, "%d", &startarray[i])) {
        getout = 1;
    }
}
//startbuffer is a string, startarray is an int array.

这导致startarray 的所有元素成为startbuffer 中的第一个字符。 sscanf 工作正常,但它不会移动到下一个 int 它只是停留在第一个位置。

知道有什么问题吗?谢谢。

【问题讨论】:

标签: c string input scanf


【解决方案1】:

每次调用sscanf 时都会传递相同的字符串指针。如果要“移动”输入,则每次都必须移动字符串的所有字节,这对于长字符串来说会很慢。此外,它会移动扫描的字节。

相反,您需要通过查询消耗的字节数和读取的值数来自己实现这一点。使用该信息自行调整指针。

int nums_now, bytes_now;
int bytes_consumed = 0, nums_read = 0;

while ( ( nums_now = 
        sscanf( string + bytes_consumed, "%d%n", arr + nums_read, & bytes_now )
        ) > 0 ) {
    bytes_consumed += bytes_now;
    nums_read += nums_now;
}

【讨论】:

  • bytes_consumed == strlen(string) 时,我得到nums_now 的虚假值(在应该中断循环的最后一次调用中)。这也是意料之中的吗?
  • @mangledorf 根据spec,“如果输入在第一次转换(如果有)完成之前结束,并且没有发生匹配失败,则应返回EOF。”这听起来像是零基本上被重新映射为负一。
  • 啊哈!因此,num_rows 是一个 signed 整数非常重要。这是相当微妙的。
【解决方案2】:

将字符串转换为流,然后可以使用 fscanf 获取整数。 尝试这个。 http://www.gnu.org/software/libc/manual/html_node/String-Streams.html

【讨论】:

【解决方案3】:

你是对的:sscanf 确实没有“移动”,因为没有什么可以移动。如果你需要扫描一堆整数,你可以使用strtol - 它告诉你它读取了多少,所以你可以在下一次迭代中将下一个指针反馈给函数。

char str[] = "10 21 32 43 54";
char *p = str;
int i;
for (i = 0 ; i != 5 ; i++) {
    int n = strtol(p, &p, 10);
    printf("%d\n", n);
}

【讨论】:

    【解决方案4】:

    这是 sscanf 的正确行为。 sscanf 对const char* 进行操作,而不是来自文件的输入流,因此它不会存储任何关于它所使用内容的信息。

    至于解决方法,你可以在格式字符串中使用%n来获取它到目前为止已经消耗的字符数(这是在C89标准中定义的)。

    例如sscanf("This is a string", "%10s%10s%n", tok1, tok2, &amp;numChar); numChar 将包含到目前为止使用的字符数。您可以将其用作偏移量以继续扫描字符串。

    如果字符串只包含不超过long类型(或long long类型)最大值的整数,使用strtolstrtoll。请注意,long 类型可以是 32 位或 64 位,具体取决于系统。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多