Как получить данные, а не целые строки в C? - PullRequest
2 голосов
/ 15 ноября 2009

Прямо сейчас я использую:

    char record[BUFLEN];
    if (fgets(record, BUFLEN, fp) != NULL) {

      /* some code */

    }

чтобы получить строки из ввода, например:

city=Boston;name=Bob;age=35
city=New York;name=Michael;age=29

Могу ли я использовать что-то еще в C, которое даст мне не целые строки до '\ n', а отдельные пары вроде: "city = Boston", затем "name = Bob" и т. Д.?

Ответы [ 4 ]

3 голосов
/ 15 ноября 2009

Это выглядит как один из тех относительно редких случаев, когда можно использовать scanf ().

Вы можете попробовать:

while (fscanf(fp, "%[^=]=%[^;\n]", name, value) == 2)
{
    if ((c = fgetc(fp)) == EOF)
        break;
    else if (c == ';')
        ...continue with same line...
    else if (c == '\n')
        ...wrap up current line...
    else
        ...congratulations - format error of some sort...
}

В качестве альтернативы, продолжайте использовать 'fgets ()', но используйте 'sscanf ()' в цикле, подобном этому.

Рабочий демонстрационный код:

#include <stdio.h>
int main(void)
{
    char name[20];
    char value[20];

    while (fscanf(stdin, "%19[^=]=%19[^;\n]", name, value) == 2)
    {
        int c;
        if ((c = fgetc(stdin)) == EOF)
            break;
        else if (c == ';')
            printf("name = [%s]; value = [%s]\n", name, value);
        else if (c == '\n')
            printf("name = [%s]; value = [%s]\n", name, value);
        else
            fprintf(stderr, "Ooops!\n");
    }
    return(0);
}
2 голосов
/ 15 ноября 2009

вы можете читать его по байтам одновременно, используя fgetc.

читать до = в один массив, затем до; в другом

        do {
          c = fgetc (pFile);

          if (c == ';') 
          // etc

        } while (c != EOF);
1 голос
/ 15 ноября 2009

Проверьте функцию strtok () . Последовательные вызовы будут извлекать каждый токен из строки.

Используя ваш пример:

char    record[BUFLEN];
if(fgets(record, BUFLEN, fp) != NULL) {
    char *token;

    token = strtok( record, ";" );
    while ( token != NULL )
    {
            doSomethingWith( token );
            token = strtok( NULL, ";" );
    }
}
0 голосов
/ 15 ноября 2009

Вы можете дублировать функциональность функции fgets (), указав только "fget" указанным разделителем, а не \ n. Код будет выглядеть примерно так (ЭТО PSEUDOCODE):

В этой функции «DELIM» - это разделитель, который вы хотите использовать. вместо \n, это может быть ;.

char *GOEfgets(char *buf, int BUFLEN, FILE *fp, char DELIM)
{
   int i = 0; /* counter */
   int character;

   while(character = fgetc(fp)) /* we get a char from the stream one at a time */
   {
      buf[i] = (char)character; /* store that character in the stream */

      if ((char)character == DELIM) /* if we run into our delimiter, we stop */
      {
         return buf;
      }
   }

}
...