簡體   English   中英

在fscanf中使用=作為分隔符匹配兩個字符串

[英]Match two strings with = as separator in fscanf

我的目的是提取值和由=分隔的鍵。 我最初的想法是使用%s=%s%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

知道我的表情為什么不匹配嗎?

必須分配keyvalue變量,例如

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

然后使用它們。

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);
}

您的指針未初始化。 讀取它們在C中是未定義的。您可以使用數組(如果知道編譯時的最大長度)或使用malloc分配內存。

仔細閱讀*scanf文檔,這些功能有些棘手。

"%s=%s"無法匹配, %s消耗了所有=符號,因此以下=始終是匹配失敗( %s之后的下一個字符始終是空格或EOF)。

讀取字符串時,請始終使用最大字段寬度(在某些情況下,可以安全地將其省略,但僅適用於sscanf )。 不幸的是,您必須對該值進行硬編碼(或在運行時構建格式字符串,但我不建議您這樣做)。

我不確定掃描集中的'應該做什么, %[^'=']等同於%[^'=]並匹配'=所有內容。 您可能是說%[^=]

格式字符串中(掃描集之外)的每個空格字符均被視為“跳過任何空格”,即空格( )與換行符相同。 整個格式字符串等效於

"%[^'=]=%[^'\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的最后一個參數。 這樣,您將無法再檢測最后一行是否以換行符結尾。

我最初的想法是使用%s=%s%s=%s東西,但是不幸的是它不起作用。

那僅僅是因為*scanf 不像您懷疑的那樣尊重非空白定界符。 此外,它不支持真正的正則表達式。 僅支持某些簡單類型的字符類[..]

給你的問題:

keyvalue必須靜態或動態分配,其余的可以簡化和編寫而無需fscanf (您的輸入顯然是面向行的),這可能會在某些時候給您帶來麻煩

  ...
  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] )。

// 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM