Захватывать строки в кавычках, разделенные запятыми, из файла - PullRequest
0 голосов
/ 14 февраля 2019

Допустим, я хочу получить входные данные из файла, подобного этому: -

"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' в режиме чтения str в fgets хранит правильную строку, но она не поглощается 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 голосов
/ 14 февраля 2019

Если вам просто нужно прочитать из файла, вы можете просто использовать fscanf() вместо чтения из файла в массив символов и затем использовать sscanf() для этой строки.

И вам не нужноявно введите cast, возвращаемое значение calloc().См. , нужно ли приводить malloc и 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 здесь избыточен, так как пробел будет соответствовать " Один символ пробела в строке формата соответствует любой комбинации символов пробела во входных данных "

Таким образом, конечная строка формата может быть

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

И не забудьте закрыть файлы, которые вы открыли, и освободить память, выделенную до концапрограммы типа

free(c); //for the Card pointer
fclose(fptr);
0 голосов
/ 14 февраля 2019

Используя 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;
}
0 голосов
/ 14 февраля 2019

Последний токен не заканчивается ',', поэтому вы не можете использовать %[^,] для него.Однако за ним следует '\"', поэтому вы можете использовать %[^\"] вместо:

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