I've written a simple config parser using fscanf
and now want to add a comment character (#
).
My configuration file contains three columns of which fscanf
reads and stores in their corresponding arrays. This works well, but I'm a little unsure how to write it so that "if the character read is #
then move onto the next line.
I've tried using fgetc
but that seems to only read the first character, and it appears to break the logic within my while loop.
I've tried using a modification of "%*[^\n]\n"
in my fscanf as:
while(fscanf(fp,"%d\t%f\t%f%*[^#]\n", &a[i], &b[i], &c[i]) != EOF)
but that causes a seg fault.
Config:
#hello and welcome to my config file
1666 -0.314913523 0.999804843 #blah blah
1667 -0.337279687 0.999865966
1703 -0.323162231 0.999774194
1704 -0.311984064 0.99964375
1705 -0.311984064 0.99964375
1706 -0.313381260 0.999671436
1707 -0.313170802 0.999558174
Code:
#include <iostream>
using namespace std;
#define NUM_ITEMS 50
int main()
{
FILE *fp;
fp = fopen("config.conf","r");
if(fp==NULL){
printf("No file.\n");
return -1;
}
int a[NUM_ITEMS];
float b[NUM_ITEMS];
float c[NUM_ITEMS];
int i = 0;
while(fscanf(fp,"%d\t%f\t%f", &a[i], &b[i], &c[i]) != EOF)
{
printf("-> %d %f %f\n", a[i], b[i], c[i]);
i++;
}
fclose(fp);
}
You can use fgets to read each line as a string and then check where '#' appears.
#include <stdio.h>
#define NUM_ITEMS 50
#define MAX_CHAR 500
ssize_t find_index(char *str)
{
size_t i=0U;
for (; *str!='\0'; i++)
{
if (*str++=='#')
{
return i;
}
}
return -1;
}
int main(void)
{
int a[NUM_ITEMS];
float b[NUM_ITEMS];
float c[NUM_ITEMS];
char buff[MAX_CHAR];
FILE *fp;
size_t i=0U;
ssize_t index=0U;
fp = fopen("config.conf","r");
if(!fp)
{
printf("No file.\n");
return -1;
}
while (fgets(buff,MAX_CHAR,fp))
{
index=find_index(buff);
if (index!=-1)
{
buff[index]='\0'; /* Bare in mind this will skip the newline character which fgets appends */
}
if(sscanf(buff,"%d%f%f", &a[i], &b[i], &c[i])==3) /* Checking scanf read 3 numbers */
{
printf("-> %d %f %f\n", a[i], b[i], c[i]);
i++;
}
}
return 0;
}
So find_index()
returns the location of the element # was found. Then replaced by NULL terminator.
As Jonathan pointed out in the comments, you can also use the strcspn()
function along with strlen()
(for error checking) to find the index of #.