c - fscanf 中百分号作为格式分隔符

标签 c delimiter scanf

我正在编写这段代码,该代码读取一个包含由百分号 (%) 分隔的记录的文件,然后将这些值保存在节点结构中。输入内容如下:

2%c1%d3%33445.000000%2016%4%11
1%c2%d2%234.500000%2016%4%11
0%c1%d1%123.400000%2016%4%11

每一行都是一个节点,其中包含由百分号分隔的数据。我正在使用 fscanf 读取格式化输入并将值保存在特定变量中。如果分隔符是除“%”之外的任何字符,则效果很好。

我尝试通过执行“%%”来转义百分号,但它不起作用,并且 fscanf 返回 -1。我到处寻找一种方法来做到这一点,但找不到任何东西。任何帮助将不胜感激。以下是代码片段。

int recordID;
char category[255];
char detail[255];
float amount;
int year;
int month;
int day;

while(fscanf(pFile, "%d%%%s%%%s%%%f%%%d%%%d%%%d", &recordID, category, detail, &amount, &year, &month, &day) == 7) {

    struct node* p = (struct node*) malloc(sizeof(struct node));

    p->recordID = recordID;
    copy_array(category, p->category, 255);
    copy_array(detail, p->detail, 255);
    p->amount = amount;
    p->year = year;
    p->month = month;
    p->day = day;

    add_node(p);
}

pFile 是包含上面指定的输入的文件。

谢谢!

最佳答案

问题是 %s 读取一个字符串,而你没有告诉它在分隔符处停止,所以它吞噬了 % 以及它后面的所有内容。使用 %[^%] 代替 %s:

fscanf(pFile, "%d%%%[^%]%%%[^%]%%%f%%%d%%%d%%%d", ...

如果您从未见过 scanf 说明符 %[,它的工作方式如下:%[abc] 扫描 a、b 和 c 的任意组合。 %[^abc] 扫描任何包含 a、b 或 c 的字符串。您还可以使用范围,例如 %[0-9]。否则,它就像 %s 一样,写入 char * 目标缓冲区。

(顺便说一句,任何选择 % 作为分隔符的人都应该被 Gunicorn 。我将所有 % 更改为 | ,在您的代码和数据文件中,这样我就可以在不失去理智的情况下调试它,然后在我让它工作后,最后将它们全部更改回 % 。)

<小时/>

附录:John Bollinger 是绝对正确的,您还需要担心缓冲区溢出,正如他的解决方案所示。

关于c - fscanf 中百分号作为格式分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36798387/

相关文章:

c++ - 我怎样才能使它与 C++ 中的每个定界符一起工作?

c - 带有 C 字符串的 scanf 和 strcmp

c - Scanf 在 C 中跳过每隔一个 while 循环

c - 在运行时确定操作系统

python - 如何将数组传递给使用 python 用 c 编写的共享库 (.dll)

c - C 程序建模

c - 在 C 中对 3d 数组的元素求和

javascript - 如何遍历 javascript 行分隔字符串,检查分号分隔的第一个值,并连接值相等的行?

java - 在 Java 中使用 useDelimiter

c++ - 带字符串的 Scanf 函数