从文件中捕获用逗号分隔的带引号的字符串

时间:2019-02-14 11:13:39

标签: c file file-handling

假设我想从这样的文件中获取输入:-

"8313515769001870,GRKLK,03/2023,eatcp,btlzg"
"6144115684794523,ZEATL,10/2033,arnne,drrfd"

对于我做的结构如下

typedef struct{
char Card_Number[20];
char Bank_Code[6];
char Expiry_Date[8];
char First_Name[30];
char Last_Name[30];
}Card;

这是我尝试在读取模式下从名为“ file”的文件中读取输入的内容,fgets中的str存储了正确的字符串,但没有被c [i]吸收:

FILE * fptr;
int count=0;
fptr= fopen("file","r");
Card *c = (Card*)calloc(10,sizeof(Card));
printf("StartAlloc\n");
int i=0;
char str[1000];
fgets(str,80,fptr);
if(fptr==NULL)
{return 0;}
do{
     sscanf(str,"\"%[^,],%[^,],%[^,],%[^,],%[^,]\" \n",c[i].Card_Number,c[i].Bank_Code,c[i].Expiry_Date,c[i].First_Name,c[i].Last_Name);
i++;

}while(fgets(str,80,fptr)!=NULL);

我不明白为什么正则表达式%[^,]不捕获单个元素,我浪费了很多时间,将不胜感激。

3 个答案:

答案 0 :(得分:1)

最后一个令牌不以','结尾,因此不能使用%[^,]。但是,其后是'\"',因此您可以使用%[^\"]代替:

sscanf(str,"\"%[^,],%[^,],%[^,],%[^,],%[^\"]\" \n",c[i].Card_Number,c[i].Bank_Code,c[i].Expiry_Date,c[i].First_Name,c[i].Last_Name);

答案 1 :(得分:0)

如果只需要从文件中读取,则可以只使用fscanf()而不是从文件中读取字符数组,然后对该字符串使用sscanf()

您不必显式地键入强制转换calloc()的返回值。参见is it necessary to type-cast malloc and calloc


你在做

if(fptr==NULL)
{return 0;}

之后,您尝试从文件中读取。如果无法打开文件,则程序将在控件到达此if语句之前崩溃。

在打开文件后立即放置此支票

FILE *fptr = fopen("file", "r");
if(fptr==NULL)
{
    return EXIT_FAILURE;
}

和返回值0通常表示成功。由于找不到输入文件是错误,请尝试返回EXIT_FAILURE


在最后一个%[^,]" in the format string of sscanf function in your program, there is no comma for the last entry of each line in the input file. So change it to read till the last“`中找到了。

此外,格式字符串的末尾还有一个空格,后跟\n\n在这里是多余的,因为空格将匹配“ One white-space character in format-string matches any combination of white-space characters in the input

所以最终的格式字符串可能是

"\"%[^,],%[^,],%[^,],%[^,],%[^\"]\" "

别忘了关闭您打开的文件并释放程序结束之前分配的内存,例如

free(c); //for the Card pointer
fclose(fptr);

答案 2 :(得分:0)

使用正确格式的fscanf(),您可以从每一行中检索所需的元素:

"\"%[^,]%*c %[^,]%*c %[^,]%*c %[^,]%*c %[^\"]%*c\n" 
  

使用以前的格式时,将忽略开头的引号(\"),并捕获用逗号分隔的字符串(%[^,]%*c)。最后,舍弃引号(%[^\"]%*c),并考虑换行符(\n),以便读取下一行。

这是将其集成到代码中的方法:

while (fscanf(file, "\"%[^,]%*c %[^,]%*c %[^,]%*c %[^,]%*c %[^\"]%*c\n", c[i].Card_Number, c[i].Bank_Code, c[i].Expiry_Date, c[i].First_Name, c[i].Last_Name) != -1 ) i++;

用于测试目的的完整代码段:

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    char Card_Number[20];
    char Bank_Code[6];
    char Expiry_Date[8];
    char First_Name[30];
    char Last_Name[30];
}Card;

int main(){
    FILE *file;
    file = fopen("data.csv", "r");
    int i=0;
    Card *c = (Card*)calloc(10,sizeof(Card));

    while (fscanf(file, "\"%[^,]%*c %[^,]%*c %[^,]%*c %[^,]%*c %[^\"]%*c\n", c[i].Card_Number, c[i].Bank_Code, c[i].Expiry_Date, c[i].First_Name, c[i].Last_Name) != -1 ) {
        printf("%s | %s | %s | %s | %s \n", c[i].Card_Number, c[i].Bank_Code, c[i].Expiry_Date, c[i].First_Name, c[i].Last_Name);
        i++;
    }
    fclose(file);
    return 0;
}
相关问题