Reputation: 23
I'm having a problem reading in values using sscanf() with delimiters.
sscanf(line, "%15[^:]:%20[^:]:%d:%d:%50[^:]:%25[^:]:%25[^\n]",
string1, string2, &value1, &value2, string3, string4, string5);
There's only a problem when line is something like:
abc:defg:1:2::hijk:no
When I print out the strings/values, everything is normal up until 'string 3'. It outputs some weird character, then 'string4' outputs an empty space and string5 outputs a similar weird character.
Anybody have any idea how I can scan in the right values?
edit: I meant abc:defg:1:2::hijk:no, not abc:defg:1:2::hijk:lm:no
Upvotes: 1
Views: 1788
Reputation: 141628
The problem is that the [
specifier causes matching failure if it does not match any characters. The scanf
function stops reading when a matching failure occurs.
The garbage you see is because you are printing out uninitialized variables (the scanning never got so far as to fill in those variables).
If you want to allow zero or more characters for a character field, you can't use a string with %[
followed by some other stuff.
Alternatives include:
scanf
which keep going even if the previous one failedA regex library might be the simplest option.
Upvotes: 2
Reputation: 40155
use strsep
like below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strsep(char **sp, const char *sep);
int main(){
char line[] = "abc:defg:1:2::hijk:no\n";
int value1, value2;
char string1[16];
char string2[20];
char string3[51];
char string4[26];
char string5[26];
char *p = line;
/*
sscanf(line, "%15[^:]:%20[^:]:%d:%d:%50[^:]:%25[^:]:%25[^\n]",
string1, string2, &value1, &value2, string3, string4, string5);
*/
strcpy(string1, strsep(&p, ":"));//or strncpy, etc.
strcpy(string2, strsep(&p, ":"));
value1 = atoi(strsep(&p, ":"));
value2 = atoi(strsep(&p, ":"));
strcpy(string3, strsep(&p, ":"));
strcpy(string4, strsep(&p, ":"));
strcpy(string5, strsep(&p, ":\n"));
printf("%s %s %d %d \"%s\" %s %s\n",
string1, string2, value1, value2, string3, string4, string5);
return 0;
}
See the following links for strsep
.
strsep
strsep
is not a standard function.
if it does not exist, be implemented as follows(E.g) :
char *strsep(char **sp, const char *sep){
char *p, *s;
if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL);
s = *sp;
p = s + strcspn(s, sep);
if (*p != '\0') *p++ = '\0';
*sp = p;
return(s);
}
Upvotes: 0
Reputation: 108978
You need to check the return value from scanf()
calls
errno = 0;
int chk = sscanf(line, "%15[^:]:%20[^:]:%d:%d:%50[^:]:%25[^:]:%25[^\n]",
string1, string2, &value1, &value2, string3, string4, string5);
switch (chk) {
case 7: /* all ok */;
break;
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: /* not enough variabes were assigned a value */;
break;
case EOF: /* error reading data */;
/* use ferror() and/or feof() and errno to determine cause of error */;
break;
default: /* no other cases are possible */;
break;
}
Upvotes: 2
Reputation: 1346
try this..( &
is missing for scanning int
)
sscanf(line, "%15[^:]:%20[^:]:%d:%d:%50[^:]:%25[^:]:%25[^\n]",
string1, string 2, &value1, &value2, string3, string4, string5);
Upvotes: 1