c - scanf()、sscanf() 或 fscanf() 中的 %[] 或 %[^] 说明符是否将输入存储在以 null 结尾的字符数组中?

标签 c string scanf format-specifiers character-arrays

这是Beez C 指南 (LINK)讲述了 %[]格式说明符:

It allows you to specify a set of characters to be stored away (likely in an array of chars). Conversion stops when a character that is not in the set is matched.

如果您能澄清由此前提产生的一些基本问题,我将不胜感激:

1) 将这两个格式说明符获取的输入存储在参数(类型 char* )中作为字符数组还是带有 \0 的字符数组?终止符(字符串)?如果不是字符串,如何将其存储为字符串,例如下面的程序,我们希望将字符序列作为字符串获取并在遇到特定字符(在否定字符集中)时停止?

2) 我的程序似乎建议停止处理 %[^|]否定字符时的说明符 |遇到了。但是当它为下一个格式说明符再次启动时,它是否从先前停止的否定字符开始?在我的程序中,我打算忽略 |因此我使用了%*c .但是我测试发现如果我使用%c和一个类型为 char 的附加参数, 然后是字符 |确实存储在该参数中。

3) 最后但对我来说至关重要的是,为 %s 传递字符数组有什么区别? printf() 中的格式说明符和一个字符串(以 NULL 结尾的字符数组)?在我的另一个名为 character array vs string 的程序中,我已经为 %s 传递了一个字符数组(不是以 NULL 结尾) printf() 中的格式说明符它会像字符串一样打印出来。有什么区别?

//程序说明%[^]说明符

#include<stdio.h>

int main()
{
char *ptr="fruit|apple|lemon",type[10],fruit1[10],fruit2[10];

sscanf(ptr, "%[^|]%*c%[^|]%*c%s", type,fruit1, fruit2);
printf("%s,%s,%s",type,fruit1,fruit2);
}

//字符数组 vs 字符串

#include<stdio.h>

int main()
{
char test[10]={'J','O','N'};
printf("%s",test);
}

输出 JON

//使用%c代替%*c

#include<stdio.h>

int main()
{
char *ptr="fruit|apple|lemon",type[10],fruit1[10],fruit2[10],char_var;

sscanf(ptr, "%[^|]%c%[^|]%*c%s", type,&char_var,fruit1, fruit2);
printf("%s,%s,%s,and the character is %c",type,fruit1,fruit2,char_var);

}

输出 fruit,apple,lemon,and the character is |

最佳答案

  1. 它是空终止的。来自 sscanf() :

    The conversion specifiers s and [ always store the null terminator in addition to the matched characters. The size of the destination array must be at least one greater than the specified field width.

  2. 被排除的字符未被扫描集使用,仍待处理。替代格式说明符:

    if (sscanf(ptr, "%9[^|]|%9[^|]|%9s", type,fruit1, fruit2) == 3)
    
  3. 数组实际上是空终止的,因为剩余的元素将被零初始化:

    char test[10]={'J','O','N' /*,0,0,0,0,0,0,0*/ };
    

如果它不是 null 终止的,那么它会一直打印直到在内存中的某处找到一个 null 字符,这可能会超出数组的末尾,从而导致未定义的行为。可以打印非空终止数组:

    char buf[] = { 'a', 'b', 'c' };
    printf("%.*s", 3, buf);

关于c - scanf()、sscanf() 或 fscanf() 中的 %[] 或 %[^] 说明符是否将输入存储在以 null 结尾的字符数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16454559/

相关文章:

Android:针对不同的应用程序风格使用不同的字符串

ruby - 根据长度读取行

c - 什么是 scanf ("%*[\n] %[^\n]", input_string);做?

c - C中读取字符串数组

java - 将字符串合并为结构化字符串

c - 从 C 中的输入文件中识别字符

尝试释放不再需要使用的内存时出现 C 段错误

c++ - 编译器如何处理 a[i] 其中 a 是数组?如果 a 是一个指针呢?

c - 指针访问有问题吗?

c - OS X KEXT 打印指针导致 <ptr>