1

let's say I want to take an input from a file like this :-

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

for a structure I made as follows

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

This is my attempt to read the input from a file named 'file' in the reading mode, the str in fgets is storing the right string but it isn't getting absorbed 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); 

I do not understand why the regex %[^,] is not capturing the individual elements, I have wasted a lot of time, and help would be greatly appreciated.

4
  • 4
    scanf format strings are not regexes. Commented Feb 14, 2019 at 11:18
  • 1
    Since the format is so simple, maybe you could use strtok instead Commented Feb 14, 2019 at 11:20
  • What does your program do? Commented Feb 14, 2019 at 11:26
  • 2
    https://ideone.com/46w9Dz Commented Feb 14, 2019 at 11:40

3 Answers 3

1

The last token doesn't end with a ',', so you can't use %[^,] for it. It is however followed by a '\"', so you can use %[^\"] instead :

sscanf(str,"\"%[^,],%[^,],%[^,],%[^,],%[^\"]\" \n",c[i].Card_Number,c[i].Bank_Code,c[i].Expiry_Date,c[i].First_Name,c[i].Last_Name); 
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, I realised this and made this change in the actual program.
@IeshaanSaxena : if that fixed your issue, please go ahead and accept the answer that helped you (ref. What should I do when someone answers my question). If your issue has't been fixed, please elaborate. As an aside : I've tested your code with my change, and it works fine here.
0

Using fscanf() with the proper format you can retrieve the desired elements from each line :

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

With the previous format, the opening quote is ignored (\"), and the strings separated by commas are captured (%[^,]%*c). Finally the the closing quote is discarded (%[^\"]%*c), and the line break considered (\n), to let next line to be read.

This is how you can integrate it in your code :

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++; 

Complete code snippet for testing purposes :

#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; } 

1 Comment

Is there a problem in using fgets()?
0

If you just need to read from the file, you could just use fscanf() instead of reading from file to a character array and then use sscanf() for that string.

And you needn't explicitly type cast the return value of calloc(). See is it necessary to type-cast malloc and calloc.


You are doing

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

after you tried to read from the file. If the file couldn't be opened the program would crash well before the control reaches this if statement.

Place this check right after opening the file like

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

and return value 0 is usually taken to mean success. Since input file not being found is an error, try returning EXIT_FAILURE instead.


And in the last %[^,]" 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"` is found.

Also, at the end of the format string, there's a space followed by a \n. The \n is redundant here as a space will match "One white-space character in format-string matches any combination of white-space characters in the input"

So the final format string could be

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

And don't forget to close the files you've opened and free the memory you've allocated before the end of the program like

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

1 Comment

Yes, I did close the file and freed the space. I understood why the last one should be till \", thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.