简体   繁体   English

fscanf()匹配C中的字符串

[英]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: 并说我已打开该文件并将其加载到*fp ,我现在想要匹配这样的行:“X”后面跟着4个数字后跟任何字符串,所以我假设它会是这样的:

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 编辑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. 所以在X修复第一个问题之前添加一个空格,但现在我才意识到一些标签中有空格。

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. fscanf(*fp, "X%4d%s", &id, label)不消耗前一行的剩余'\\n' See hint: @Some programmer dude . 见提示: @Some程序员老兄 The 2nd fscanf() simple failed and did not update id, label . 第二个fscanf()简单失败,没有更新id, label Had code checked the fscanf() return value, this could have been caught earlier. 如果代码检查了fscanf()返回值,则可能之前已经捕获过。

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. 使用fscanf(*fp, " X%4d%s", &id, label) (添加空格)或更好,编码fgets()然后sscanf()行并检查扫描的返回值。

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" , : 要阅读该其余部分 ,而不是"%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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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