我将如何读取 C 中的文本文件?

How would I read a text file in C?

我有 file.txt

123456 2,00 beer
234567 2,50 milk
345678 3,30 ice cream

我想将此信息放入我的动态二维数组中:

char **dataBase;
dataBase = (char**)malloc(NUM_OF_PROD * sizeof(char*));
for(i = 0; i < NUM_OF_PROD; i++){
           dataBase[i] = (char*)malloc(MAX_BUFFER* sizeof(char));
}

但我不知道怎么做。我们这里有 3 行。如果它是 C++,我会使用 getline() 但在这种情况下我找不到解决方案。

在您提到的评论中,您只关心实际读取文件。 以下是您读取文件的方式(目前未经测试,二进制模式):

#include <stdio.h>

int main()
{
    FILE *file = fopen("path/to/your/file/yourfile.txt", "rb");
    if(!file) return 1; //something went wrong!
    long size = fseek(file, 0, SEEK_END);
    char *buf = malloc(size);
    fread(&buf, size, 1, file); //read all contents, once
    fclose(file);
    free(buf); //because this is just an example
    return 0;
} 

有关读取文件的更多信息,只需快速 google 搜索,您几乎可以找到所需的一切。

您可以使用 fgetcrealloc 实现您自己的 getline 版本。

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

char *getline(FILE *file)
{
    size_t size = 16; // Size of memory allocated for line
    size_t len = 0;   // Characters read
    char *line = malloc(size);

    // Return NULL if memory allocation fails
    if (line == NULL)
        return NULL;

    for(;;) {
        int c;

        switch (c = fgetc(file)) {
            // If End Of File is met, return the line up until this point
            // if anything has been read
            case EOF:
            if (len == 0) {
                free(line);
                return NULL;
            }
            else {
                line[len+1] = '[=10=]';
                return line;
            }

            case '\n':
            line[len+1] = '[=10=]'; // NUL terminate the string
            return line;

            default:
            line[len++] = c;
        }

        // If the string plus NUL terminator is longer than size
        // double the size of line
        if (len + 1 >= size) {
            size *= 2;
            line = realloc(line, size);
            // Return NULL if memory allocation fails
            if (line == NULL)
                return NULL;
        }
    }
}

还有很多 free/open 可以在网上找到相同功能的源代码实现。例如this GPL 2 one。如果您使用的是 POSIX 系统(例如 OS X 或 Linux),则在 stdio.h.[=17 中已经找到了 getline 的版本=]

我通常对文件逐行使用 fgets() 函数(前提是它是文本文件)。

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

#define LINELEN 200
#define NAMELEN  40

struct PRICELIST
{
  char item[NAMELEN];
  float price;
  unsigned int order_no;
  struct PRICELIST *next;
  struct PRICELIST *prev;
};

void list_print_node (struct PRICELIST *node)
{
  printf ("%d   %4.2f   %s\n", node->order_no, node->price, node->item);
}

void list_print (struct PRICELIST *head)
{
  printf ("Order #  Price  Item\n");
  printf ("------------------------------\n");
  while (head)
  {
    list_print_node (head);
    head = head->next;
  }
}

void list_delete (struct PRICELIST *head)
{
  if (head)
  {
    /* recursive call */
    list_delete (head->next);
    free (head);
  }
}

struct PRICELIST *list_read (char *filename)
{
  FILE *file;
  char line[LINELEN];
  struct PRICELIST *pricelist, *node, *prev;
  char *p;
  size_t len;

  file = fopen (filename, "r");
  if (file == NULL)
  {
    perror (filename);
    return NULL;
  }
  pricelist = NULL;
  prev = NULL;
  while (1)
  {
    if (fgets (line, sizeof(line), file) == NULL)
      break;

    /* eat the newline at the end of the buffer, be CR/CRLF agnostic .. */
    len = strlen (line) - 1;
    if (line[len] == '\r' || line[len] == '\n')
    {
      line[len] = '[=10=]';
      len --;
    }
    if (line[len] == '\r' || line[len] == '\n')
      line[len] = '[=10=]';

    /* allocate a new node in the list */
    node = malloc (sizeof (struct PRICELIST));
    if (node)
    {
      /* now use sscanf() for getting single elements */
      sscanf (line, "%d %f", &node->order_no, &node->price);

      /* since the item name might contain spaces this is not so easy .. */
      p = line;
      while (isspace(*p)) p++;
      while (isdigit(*p)) p++;
      while (isspace(*p)) p++;
      while (isdigit(*p)) p++;
      while (ispunct(*p)) p++;
      while (isdigit(*p)) p++;
      while (isspace(*p)) p++;
      strncpy (node->item, p, sizeof(node->item));
      node->next = NULL;

      /* if this is the first node of the list assign the head to it */
      if (pricelist == NULL)
        pricelist = node;

      /* append the new node to the end of the linked list */
      if (prev)
        prev->next = node;
      node->prev = prev;

      /* save it for the next entry */
      prev = node;
    }
  }
  /* we are done with the file, close it */
  fclose (file);
  return pricelist;
}

/* let's test it */
int main (int argc, char *argv[])
{
  struct PRICELIST *pricelist;

  if (argc < 2)
  {
    printf ("Usage: %s filename\n", argv[0]);
    return 0;
  }
  pricelist = list_read (argv[1]);
  if (pricelist)
  {
    /* print the list */
    printf ("This is the price list (filename '%s'):\n\n", argv[1]);
    list_print (pricelist);

    /* delete the list */
    list_delete (pricelist);
  }
  return 0;
}