匹配两个字符串,其中=作为fscanf中的分隔符

时间:2014-10-16 09:39:58

标签: c scanf

我的目标是提取值和由=分隔的键。我最初的想法是使用类似%s=%s的东西,但不幸的是它不起作用。

所以我有一个文件:

A=1
B=2

所以我打开文件:

char *key;
char *value;

FILE* file = fopen("./file", "r");
do {
  fscanf(file, "%[^'=']=%[^'\n']\n", key, value);
  printf("key:%s value:%s\n", key, value);
} while(!feof(file));

然而,键和值都返回:

key:1 value:1
key:2 value:2

知道为什么我的表情不匹配?。

5 个答案:

答案 0 :(得分:2)

必须分配

keyvalue个变量,例如

char key[100];
char value[1000];

然后使用它们。

答案 1 :(得分:1)

char key[16];//char *key;//not point to memory for store.
char value[16];

FILE *file = fopen("./file", "r");
while(2==fscanf(file, " %[^=]=%[^\n]", key, value)){
  printf ("key:%s value:%s\n", key, value);
}

答案 2 :(得分:1)

您的指针未初始化。在C中读取它们是未定义的。您可以使用数组(如果您知道编译时的最大长度)或使用malloc分配内存。

仔细阅读*scanf文档,这些功能有点棘手。

"%s=%s"无法匹配,%s会消耗所有=个符号,因此以下=始终是匹配失败(%s之后的下一个字符始终是空白或EOF)。

在读取字符串时,始终使用最大字段宽度(在某些情况下,可以安全地省略它,但仅适用于sscanf)。不幸的是,你必须对该值进行硬编码(或者在运行时建立格式字符串,但我不建议你这样做)。

我不确定扫描集中'应该做什么,%[^'=']相当于%[^'=]并且匹配'和{=之外的所有内容{1}}。你可能意味着%[^=]

格式字符串中的每个空白字符(扫描集外)都被视为"跳过任何空格",即空格()是相同的作为换行符。整个格式字符串相当于

"%[^'=]=%[^'\n] " // Note the space at the end

要匹配文字换行符,您需要使用扫描集(带有长度)。

始终检查*scanf的返回值(也适用于fopen和任何其他可能失败的功能。)

char key[64];   // Or whatever is appropriate for you,
char value[64]; // remember the 0-terminator needs one byte

FILE *file = fopen("./file", "r");
if(!file) {
    perror("./file");
    exit(1);
}
for(;;) {
    int e = fscanf(file, "%63[^=]=%63[^\n]%1[\n]", key, value, (char[2]){ 0 });
    if(e == -1) {
        if(ferror(file)) {
            perror("reading from ./file");
            // handle read error
        } else { // EOF reached on first character of line
            break;
        }
    } else if(e < 3) {
        // handle invalid input
    } else {
        printf("key:%s value:%s\n", key, value);
    }
}

或者,您可以对"%63[^=]=%63[^\n]%*1[\n]"中的最后一个换行使用赋值抑制,并省略fscanf的最后一个参数。通过这样做,您无法再检测到最后一行是否以换行符结束。

答案 3 :(得分:0)

  

我最初的想法是使用像%s=%s这样的东西,但不幸的是   不起作用。

这仅仅是因为*scanf 不会尊重您怀疑的非空白分隔符。此外,它不支持真正的正则表达式。只支持某种简单类型的字符类[..]

解决您的问题:

keyvalue必须分配静态或动态,其余的可以简化和编写而不需要fscanf(您的输入显然是面向行的),这可能会让你{ {3}}:

  ...
  FILE* fh = fopen("file", "r");
  char buffer[1024]; /* line buffer for reading file if file is line-oriented */

  while( fgets(buffer, sizeof(buffer), fh) ) {
     char key[256], val[256];
     sscanf(buffer, "%[^=]=%[^\n]", key, val);
     printf("key:%s val:%s\n", key, val);
  } 
  fclose(fh);
  ...

根据您的输入编辑扫描缓冲区的长度(key[256]val[256])。

答案 4 :(得分:0)

// sample working code
#include<stdio.h>
#include<stdlib.h>

int main(void) {

    FILE* file = fopen("./file", "r");

    if(NULL == file) {
        printf("Failed to open file\n");
        return EXIT_FAILURE;
    }

    do {
        char key[256];
        char value[256];
        fscanf(file, "%[^'=']=%[^'\n']\n", key, value);
        printf("key:%s value:%s\n", key, value);
    }while(!feof(file));

    fclose(file);

    return EXIT_SUCCESS;
} // End of main()

示例输出:

key:A value:1
key:B value:2
key:C value:3