I am writing a program that is capable of reading a matrix supplied from a text file. One intended feature of this program is that it should be capable of detecting various delimiters in the text file.
So, for example, these inputs should be interpreted equally:
1,2,3,4
5,6,7,8
9,10,11,12
1:2:3:4
5:6:7:8
9:10:11:12
My code for detecting the delimiting character is as follows:
#include <stdio.h>
#include <limits.h>
static int isNumeric(unsigned char c)
{
switch(c) {
case '.':
case '0' ... '9':
return 1;
default:
return 0;
}
}
unsigned char findDelimeter(FILE * f)
{
rewind(f);
int c;
unsigned char delimeter = '\0';
long long int frequencies[UCHAR_MAX] = { 0 };
long long int maxFrequency = 0;
while ((c = fgetc(f)) != EOF) {
frequencies[c]++;
}
for (c = 0; c < UCHAR_MAX; c++) {
if (frequencies[c] > maxFrequency && !(isNumeric(c) || c == '\n')) {
maxFrequency = frequencies[c];
delimeter = c;
}
}
return delimeter;
}
I have a few concerns about this code:
- Are the large data types, like
long long int
necessary in thefindDelimeter
function? Would it be better to use the types defined instdint.h
, likeuint64_t
? My intention was to support very large files. - How can I deal with the situation where an arbitrary number of spaces follow a delimiting character?
Regarding the last point, I would also like my code to be able to deal with text files that may use a space or a non-space delimiter followed by an arbitrary number of spaces. For example, the following inputs should be interpreted equally:
1 2 3 4
5 6 7 8
9 10 11 12
1, 2, 3, 4
5,6, 7, 8
9, 10, 11,12
Currently, it detects the delimiter as the most frequent, non-numeric character. So in the last example, it would detect the space character as the delimiter since it is the most common non-numeric character, and it would mistakenly include the comma as part of the number when interpreting it. One solution that I thought of was modifying the findDelimeter
function to return a string (er, character array), but I anticipate that would not be able to deal with an arbitrary number of spaces.
Also, as usual, I very much appreciate any stylistic comments or potential bugs.
case '0' ... '9':
a `case can only have one value. so the code needs a series of case statements with one case statement for each value of interest. \$\endgroup\$