繁体   English   中英

如何读取C文件中方括号内的字符串,每行包含多个这样的字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM