I'm writing a function that is supposed to read a string of numbers, separated by commas. The format of the string is as following:
"1, 2, 3"
The only "rule" is that the function will tolerate any spaces or tabs, as long as there's one comma between each number.
If the string is valid, the numbers are to be stored in a linked list.
for instance, the following strings are valid:
"1,2,14,2,80"
" 250 , 1, 88"
but the following are not valid:
" 5, 1, 3 ,"
"51, 60, 5,,9"
I first tried my luck with strtok() (using delimiters ", \t", but from what i understand at the moment, it's impossible to check for errors. So I wrote my own function, but I'm extremely unhappy with it - I think the code is pretty bad, and although it seems to work, I'd really like to know if there is a cleaner, easier way to implement such a function.
My function is:
void sliceNumbers(char * string)
{
/*flag which marks if we're expecting a comma or not*/
int comma = FALSE;
/*Are we inside a number?*/
int nFlag = TRUE;
/*error flag*/
int error = FALSE;
/*pointer to string start*/
char * pStart = string;
/*pointer to string end*/
char * pEnd = pStart;
/*if received string is null*/
if (!string)
{
/*add error and exit function*/
printf("You must specify numbers");
return;
}
/*this loop checks if all characters in the string are legal*/
while (*pStart != '\0')
{
if ((isdigit(*pStart)) || (*pStart == ',') || (*pStart == ' ') || (*pStart == '\t'))
{
pStart++;
}
else
{
char tmp[2];
tmp[0] = *pStart;
tmp[1] = 0;
printf("Invalid character");
error = TRUE;
pStart++;
}
}
if (!error)
{
pStart = string;
if (*pStart == ',')
{
printf("Cannot start data list with a comma");
return;
}
pEnd = pStart;
while (*pEnd != '\0')
{
if (comma)
{
if (*pEnd == ',')
{
if (!nFlag)
{
}
if (*(pEnd + 1) == '\0')
{
printf("Too many commas");
return;
}
*pEnd = '\0';
/*Add the number to the linked list*/
addNumber(pStart, line, DC);
comma = FALSE;
nFlag = FALSE;
pStart = pEnd;
pStart++;
pEnd = pStart;
}
else if (isdigit(*pEnd))
{
if (!nFlag)
{
printf("numbers must be seperated by commas");
pEnd++;
}
else
{
if (*(pEnd + 1) == '\0')
{
pEnd++;
/*Add the number to the linked list*/
addNumber(pStart);
comma = FALSE;
nFlag = FALSE;
pStart = pEnd;
pStart++;
pEnd = pStart;
}
else
{
pEnd++;
}
}
}
else if (*pEnd == '\0')
{
if (nFlag)
{
/*Add the number to the linked list*/
addNumber(pStart, line, DC);
}
else
{
printf("Too many commas");
}
}
else if (*pEnd == ' ' || *pEnd == '\t')
{
nFlag = FALSE;
pEnd++;
}
}
else
{
if (*pEnd == ',')
{
printf("There must be only 1 comma between numbers");
return;
}
else if (isdigit(*pEnd))
{
if (*(pEnd + 1) == '\0')
{
pEnd++;
/*Add the number to the linked list*/
addnumber(pStart, line, DC);
comma = FALSE;
nFlag = FALSE;
pStart = pEnd;
pStart++;
pEnd = pStart;
}
else
{
pStart = pEnd;
pEnd++;
nFlag = TRUE;
comma = TRUE;
}
}
else if (*pEnd == ' ' || *pEnd == '\t')
{
if (!nFlag)
{
pEnd++;
}
else
{
pEnd++;
}
}
}
}
}
}