Как я могу считать XML-файл в буфер в C?

В javascript вы можете использовать метод сортировки для сортировки массива.

Здесь ваш ответ выглядит как массив json, вы можете вызвать sort() для него и дать ему специальную функцию для сортировки. Пример:

var myArray = [
  {
    stock: "available",
    name: "Higher Engineering maths"
  },
  {
    stock: "available",
    name: "Qantum Physics"
  },
  {
    stock: "available",
    name: "Biology"
  }
]

myArray.sort(function (item1, item2) => {
    //if the result of this method is negative, item2 is considered "bigger" than item1, and vice versa
    return item1.name.toLowerCase() < item2.name.toLowerCase() ? -1 : 1
})

это отсортирует ваш массив в алфавитном порядке поля name. Обратите внимание, что toLowerCase() не является необходимым, но рекомендуется, если вы не контролируете ввод и не хотите обрабатывать заглавные буквы по-разному.

5
задан Dinah 21 December 2008 в 06:14
поделиться

7 ответов

Действительно ли чтение является содержанием файла в единственный, простой буфер действительно, что Вы хотите сделать? XML-файлы должны обычно там анализироваться, и можно сделать, это с библиотекой как libxml2, только для предоставления одного примера (но особенно, реализован в C).

7
ответ дан 18 December 2019 в 07:32
поделиться

И если бы Вы хотите проанализировать XML, не просто читая его в буфер (что-то, что не было бы XML-конкретно, видеть ответы Christoph и Baget), можно использовать, например, libxml2:

#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>

int main(int argc, char **argv) {
   xmlDoc *document;
   xmlNode *root, *first_child, *node;
   char *filename;

   if (argc < 2) {
     fprintf(stderr, "Usage: %s filename.xml\n", argv[0]);
     return 1;
   }
   filename = argv[1];

  document = xmlReadFile(filename, NULL, 0);
  root = xmlDocGetRootElement(document);
  fprintf(stdout, "Root is <%s> (%i)\n", root->name, root->type);
  first_child = root->children;
  for (node = first_child; node; node = node->next) {
     fprintf(stdout, "\t Child is <%s> (%i)\n", node->name, node->type);
  }
  fprintf(stdout, "...\n");
  return 0;
}

На машине Unix Вы обычно компилируете вышеупомянутое с:

% gcc -o read-xml $(xml2-config --cflags) -Wall $(xml2-config --libs) read-xml.c
7
ответ дан 18 December 2019 в 07:32
поделиться

Надо надеяться, ISOC без ошибок кодирует, чтобы считать содержание файла и добавить '\0' символов:

#include <stdlib.h>
#include <stdio.h>

long fsize(FILE * file)
{
    if(fseek(file, 0, SEEK_END))
        return -1;

    long size = ftell(file);
    if(size < 0)
        return -1;

    if(fseek(file, 0, SEEK_SET))
        return -1;

    return size;
}

size_t fget_contents(char ** str, const char * name, _Bool * error)
{
    FILE * file = NULL;
    size_t read = 0;
    *str = NULL;
    if(error) *error = 1;

    do
    {
        file = fopen(name, "rb");
        if(!file) break;

        long size = fsize(file);
        if(size < 0) break;

        if(error) *error = 0;

        *str = malloc((size_t)size + 1);
        if(!*str) break;

        read = fread(*str, 1, (size_t)size, file);
        (*str)[read] = 0;
        *str = realloc(*str, read + 1);

        if(error) *error = (size != (long)read);
    }
    while(0);

    if(file) fclose(file);
    return read;
}
3
ответ дан 18 December 2019 в 07:32
поделиться

Можно использовать статистику () функция для получения размера файла. затем выделите буфер с помощью malloc после него, читая освобожденное использование файла.

код будет чем-то как этот:

struct stat file_status;
char *buf = NULL;
FILE * pFile;

stat("tmp.xml", &file_status);
buf = (char*)malloc(file_status.st_size);
pFile = fopen ("tmp.xml","r");
fread (buf,1,file_status.st_size,pFile);

fclose(pFile);
2
ответ дан 18 December 2019 в 07:32
поделиться

Вот полная программа, которая читает в целом XML-файле (действительно, любой файл), в буфер. Это включает почти столько проверки ошибок, сколько было бы полезно.

N.B. во всем выполняют main(). Превращение его в вызываемую функцию оставляют как осуществление для читателя.

(Протестированный, скомпилированный с GCC 4.3.3. Переключатели были -Wall -W --pedantic --ansi.)

Комментарии к этому будут обращены приблизительно через восемь часов.

#include <stdio.h>
#include <stdlib.h>


int main (int argc, char *argv[]) {
 char   *buffer;        /* holds the file contents. */
 size_t  i;             /* indexing into buffer. */
 size_t  buffer_size;   /* size of the buffer. */
 char   *temp;          /* for realloc(). */
 char    c;             /* for reading from the input. */
 FILE   *input;         /* our input stream. */


 if (argc == 1) {
      fprintf(stderr, "Needs a filename argument.\n");
      exit(EXIT_FAILURE);
 }
 else if (argc > 2) {
      fprintf(stderr, "Well, you passed in a few filenames, but I'm only using %s\n", argv[1]);
 }

 if ((input = fopen(argv[1], "r")) == NULL) {
      fprintf(stderr, "Error opening input file %s\n", argv[1]);
      exit(EXIT_FAILURE);
 }

 /* Initial allocation of buffer */
 i = 0;
 buffer_size = BUFSIZ;
 if ((buffer = malloc(buffer_size)) == NULL) {
      fprintf(stderr, "Error allocating memory (before reading file).\n");
      fclose(input);
 }

 while ((c = fgetc(input)) != EOF) {
      /* Enlarge buffer if necessary. */
      if (i == buffer_size) {
       buffer_size += BUFSIZ;
       if ((temp = realloc(buffer, buffer_size)) == NULL) {
        fprintf(stderr, "Ran out of core while reading file.\n");
        fclose(input);
        free(buffer);
        exit(EXIT_FAILURE);
       }
       buffer = temp;
      }

      /* Add input char to the buffer. */
      buffer[i++] = c;
 }

 /* Test if loop terminated from error. */
 if (ferror(input)) {
      fprintf(stderr, "There was a file input error.\n");
      free(buffer);
      fclose(input);
      exit(EXIT_FAILURE);
 }

 /* Make the buffer a bona-fide string. */
 if (i == buffer_size) {
      buffer_size += 1;
      if ((temp = realloc(buffer, buffer_size)) == NULL) {
       fprintf(stderr, "Ran out of core (and only needed one more byte too ;_;).\n");
       fclose(input);
       free(buffer);
       exit(EXIT_FAILURE);
      }
      buffer = temp;
 }
 buffer[i] = '\0';

 puts(buffer);

 /* Clean up. */
 free(buffer);
 fclose(input);

 return 0;
}
0
ответ дан 18 December 2019 в 07:32
поделиться

Я полагаю, что вопрос был о парсинге XML а не о чтении файла, однако OP должен действительно разъяснить это.
Любым путем Вы получили много примера, как считать файл.
Другая опция к xml, анализирующему в дополнительном к sgm предложению, будет библиотекой Expat

0
ответ дан 18 December 2019 в 07:32
поделиться

Предложение: Используйте размещение в ОЗУ

Это имеет потенциал для сокращения бесполезного копирования данных. Прием должен попросить у ОС то, что Вы хотите, вместо того, чтобы делать его. Вот реализация, которую я сделал ранее:

mmap.h

#ifndef MMAP_H
#define MMAP_H

#include <sys/types.h>

struct region_t {
  void *head;
  off_t size;
};

#define OUT_OF_BOUNDS(reg, p) \
  (((void *)(p) < (reg)->head) || ((void *)(p) >= ((reg)->head)+(reg)->size))

#define REG_SHOW(reg) \
  printf("h: %p, s: %ld (e: %p)\n", reg->head, reg->size, reg->head+reg->size);

struct region_t *do_mmap(const char *fn);
#endif

mmap.c

#include <stdlib.h>

#include <sys/types.h>  /* open lseek             */
#include <sys/stat.h>   /* open                   */
#include <fcntl.h>      /* open                   */
#include <unistd.h>     /*      lseek             */
#include <sys/mman.h>   /*            mmap        */

#include "mmap.h"

struct region_t *do_mmap(const char *fn)
{
  struct region_t *R = calloc(1, sizeof(struct region_t));

  if(R != NULL) {
    int fd;

    fd = open(fn, O_RDONLY);
    if(fd != -1) {
      R->size = lseek(fd, 0, SEEK_END);
      if(R->size != -1) {
        R->head = mmap(NULL, R->size, PROT_READ, MAP_PRIVATE, fd, 0);
        if(R->head) {
          close(fd); /* don't need file-destructor anymore. */
          return R;
        }
        /*                no clean up of borked (mmap,) */
      }
      close(fd);   /* clean up of borked (lseek, mmap,) */
    }
    free(R); /* clean up of borked (open, lseek, mmap,) */
  }
  return NULL;
}
0
ответ дан 18 December 2019 в 07:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: