简体   繁体   中英

fscanf() match string in C

I have a file laid out like this:

X1034Example
X1234Example2
Y2934Example3

and say I have opened that file and loaded it into *fp , I now want to match lines like this: "X" followed by 4 digits followed by any string so I assumed that would be something like this:

FILE **fp;
if ((*fp = fopen(fileName, "r")) == NULL) {
    printf("Unable to read file: %d: %s\n", errno, strerror(errno));
    exit(1);
}

int id; char label[64];
fscanf(*fp, "X%4d%s", &id, label)

However, this doesn't work properly and for the file specified I tested using this snippet:

fscanf(*fp, "X%4d%s", &id, label);
printf("%d\n", id);
printf("%s\n", label);

fscanf(*fp, "X%4d%s", &id, label);
printf("%d\n", id);
printf("%s\n", label);

and the output I had was

1
Example
1
Example

is this just due to the non-deterministic behaviour with pointer or am I doing something wrong?

Edit 1

So adding a space before the X fixed the first issue but now I just realised that some of the labels have spaces in.

For example:

X1245Example Text Here

fscanf(*fp, " X%4d%s", &id, label);
printf("%d\n", id);
printf("%s\n", label);

should produce:

1245
Example Text Here

is this just due to the non-deterministic behaviour with pointer or am I doing something wrong?

fscanf(*fp, "X%4d%s", &id, label) does not consume the leftover '\\n' of the previous line. See hint: @Some programmer dude . The 2nd fscanf() simple failed and did not update id, label . Had code checked the fscanf() return value, this could have been caught earlier.

Use fscanf(*fp, " X%4d%s", &id, label) (Add space) or better yet, code fgets() and then sscanf() the line and check the return value of the scan.

int id; char label[64];
char buffer[sizeof label * 2];  // form a generous buffer

if (fgets(buffer, sizeof buffer, stdin)) {
  if (sscanf(*fp, "X%4d%63s", &id, label) == 2) {
    printf("%d\n", id);
    printf("%s\n", label);
  } else {
    Failed();
  }
}

To read the rest of the line , instead of "%s" , :

if (fgets(buffer, sizeof buffer, stdin)) {
  if (sscanf(*fp, "X%4d%63[^\n]", &id, label) == 2) {
    printf("%d\n", id);
    printf("<%s>\n", label);  // added <> to help denote spaces

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM