[英]How to read multiple strings in C one in a line, each containing spaces?
[英]How do I read a string enclosed within square braces in a file in C with each line containing several such strings
问题文件:
[well lol], [wtf bro? 24], [0183188383], [3000.000000], [4000.000000], [12/12/2012]
[chow hai], [pukima jalan], [6969696969], [6969.000000], [6969699.000000], [6/9/1969]
码:
typedef struct Customer {
char name[50];
char billing_address[100];
char phone_number[15];
double amount_paid;
double amount_due;
char date[20];
} Customer;
Customer customer;
FILE *file = fopen("customers.txt", "ab+");
while (!feof(file)) {
fscanf(file, "[%s], [%s], [%s], [%lf], [%lf], [%s]\n", &customer.name, &customer.billing_address, customer.phone_number, &customer.amount_paid, &customer.amount_due, customer.date);
}
问题:
在上面的代码中,我要尝试的是将每个记录值解析到Customer
结构中的相应字段中。 现在我们知道“%s”将不会读取空格。 由于%s
无法正常工作,我将如何在记录中读取“ well lol”之类的值。
为什么不是重复的?
我需要解析整行,而不仅仅是接受另一个值作为所谓的重复答案。
更新为什么它不是重复的:
while (!feof(file)) {
fscanf(file, "[%[^\\n]], [%[^\\n]], [%[^\\n]], [%lf], [%lf], [%[^\\n]]\n", customer.name, customer.billing_address, customer.phone_number, &customer.amount_paid, &customer.amount_due, customer.date);
printf("%s", customer.billing_address);
if (strcmp(customer.name, search) == 0) {
printf("FOUND!!!");
}
}
我已经更新了代码,但是输出仍然错误。 我相信还有其他问题。 输出:
SEARCH A CUSTOMER PROFILE
=========================
Customer Name: a
���
您需要使用“扫描集”,该扫描集由格式字符串中的%[…]
指定。 您在这里需要小心,因为数据也包含方括号,并且您要匹配一个否定的字符集-任何不是方括号的内容。 基本思想如下:
while (fscanf(file, " [%[^]]], [%[^]]], [%[^]]], [%lf], [%lf], [%[^]]]",
customer.name, customer.billing_address, customer.phone_number,
&customer.amount_paid, &customer.amount_due, customer.date) == 6)
{
…good data to process…
}
%[^]]
表示'扫描集-否定-第一个字符为]
-扫描集的结尾。 该代码检查是否读取了6个值,如果有问题(或EOF),则停止。 请注意, while (!feof(file))
总是错误的 。
确实没有必要在数据中使用逗号和方括号。 仅使用方括号就足够了。
将其转换为MCVE:
#include <stdio.h>
typedef struct Customer {
char name[50];
char billing_address[100];
char phone_number[15];
double amount_paid;
double amount_due;
char date[20];
} Customer;
int main(void)
{
Customer customer;
FILE *file = stdin; //fopen("customers.txt", "ab+");
while (fscanf(file, " [%49[^]]], [%99[^]]], [%14[^]]], [%lf], [%lf], [%19[^]]]",
customer.name, customer.billing_address, customer.phone_number,
&customer.amount_paid, &customer.amount_due, customer.date) == 6)
{
printf("Data: <<%s>> <<%s>> <<%s>> %10.2f %10.2f <<%s>>\n",
customer.name, customer.billing_address, customer.phone_number,
customer.amount_paid, customer.amount_due, customer.date);
}
return 0;
}
请注意,在此版本中,我添加了溢出保护 -格式为%49[^]]
可防止溢出。 长度上的“一人一碰”是有意的和必要的(并且是令人讨厌的,但是它受古代和遵循古代为我们提供标准I / O库的先例的标准所赐)。
格式开头的空白并非偶然。 三种格式不会跳过前导空格: %c
, %[…]
和%n
。 如果输入来自终端而非文件,则将空白放在前面可提供更好的用户体验。 (有关更多信息,请参见scanf()
将换行符留在输入流中 (以及其他问题)。)
这是从标准输入而不是命名文件中读取的。 从scan13.c
编译为scan13
并在示例数据上运行时,它将产生:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror scan13.c -o scan13
$ cat data
[well lol], [wtf bro? 24], [0183188383], [3000.000000], [4000.000000], [12/12/2012]
[chow hai], [pukima jalan], [6969696969], [6969.000000], [6969699.000000], [6/9/1969]
$ scan13 < data
Data: <<well lol>> <<wtf bro? 24>> <<0183188383>> 3000.00 4000.00 <<12/12/2012>>
Data: <<chow hai>> <<pukima jalan>> <<6969696969>> 6969.00 6969699.00 <<6/9/1969>>
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.