I have a line: Something | Something | Something | Something
I want to use sscanf() to limit the input to " | ".
That "Something" is a string that can include any symbol like ",./@#$ etc."
sscanf(line,"%[^'|'] , %[^'|'] , %[^'|'] , %[^'|']",node->x,node->y,node->z,node->w);
// ^ - I don't know how to put the delimiters.
CodePudding user response:
" , "
will scan for optional white-space, a ,
and then more optional white-space. This is OP's key problem. It should have been " | "
to consume the '|'
separator.
"%[^'|']"
will scan for characters that are not: '
, |
. Use "%[^|]"
to scan for characters that are not |
.
"%[^'|']"
lacks a width limit - do not omit a width limit if overflow possible.
sscanf()
result deserve checking.
Use "%n"
to record the offset of the scan. Useful for detecting extra junk in the string.
Put it all together
struct {
char x[20];
char y[18];
char z[16];
char w[14];
} node;
int n = 0;
sscanf(line, " [^|] | [^|] | [^|] | [^|]%n",
node.x, node.y, node.z, node.w, &n);
if (n == 0 || line[n]) {
fprintf(stderr, "Scan failed for <%s>\n", line);
} else {
Success(); // Your code here
}
Should line
contain a '\n'
, usually that is not wanted either in node.w
.
// sscanf(line, " [^|] | [^|] | [^|] | [^|]%n",
sscanf(line, " [^|] | [^|] | [^|] | [^|\n] %n",
CodePudding user response:
To read a line, use fgets rather than scanf:
#include <stdio.h>
#include <string.h>
int main(void) {
char *x, *y, *z, *w;
printf("Enter string: ");
fflush(stdout);
char line[100];
fgets(line, sizeof line, stdin);
x = strtok(line, "|");
y = strtok(0, "|");
z = strtok(0, "|");
w = strtok(0, "\n");
printf("x:%s\ny:%s\nz:%s\nw:%s\n", x,y,z,w);
}
Enter string: Something1 | Something2 | Something3 | Something4
x:Something1
y: Something2
z: Something3
w: Something4
Enter string: foo
x:foo
y:(null)
z:(null)
w:(null)