将数据存储在列表c中

时间:2019-02-21 20:15:17

标签: c list

我的程序的想法是从文件(在这种情况下,文件包含5个名称)中读取数据,并将它们存储在列表中,因此以后我可以使用数据来例如计算最小/最大字符。到目前为止,我已经能够读取数据并将其打印出来,但是除了打印之外,我想将它们保存到列表中。我找不到解决该问题的方法,因此,我希望获得一些帮助。

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

int main(void) {

    char file, filename[25];
    FILE *f;

    printf("Enter the file name: ");
    scanf("%s", filename);

    f = fopen(filename, "r");

    if (f == NULL)
    {
        perror("No file found.\n");
        return 0;
    }

    printf("The contents of %s file are:\n", filename);

    while((file = fgetc(f)) != EOF)
        printf("%c", file);

    fclose(f);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

一个简单的示例,使用链接名称作为列表:

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

typedef struct NameList {
  char * name; 
  struct NameList * next;
} NameList;

int append(NameList ** head, NameList ** tail, char * s)
{
  NameList * l;

  if (((l = malloc(sizeof(NameList))) == NULL) ||
      ((l->name = strdup(s)) == NULL))
    /* not enough memory */
    return 0;

  l->next = NULL;
  if (*head == NULL) {
    *head = *tail = l;
  }
  else {
    (*tail)->next = l;
    *tail = l;
  }

  return 1;
}

int main(void) {
  char filename[25];
  FILE * f;

  printf("Enter the file name: ");
  if (scanf("%24s", filename) != 1)
    return 0;

  f = fopen(filename, "r");

  if (f == NULL)
  {
    puts("No file found.");
    return 0;
  }

  NameList * head = NULL;
  NameList * tail = NULL;
  char s[64];

  /* suppose a name has no space even composed and less than 64 characters */
  while (fscanf(f, "%63s", s) == 1) {
    if (!append(&head, &tail, s))
      return 0;
  }

  fclose(f);

  printf("The names in %s file are:\n", filename);

  NameList * l;

  l = head;
  while (l != NULL) {
    puts(l->name);
    l = l->next;
  }

  /* search longer name */
  size_t maxlen = 0;
  char * longer = NULL;

  l = head;
  while (l != NULL) {
    size_t ln = strlen(l->name);

    if (ln > maxlen) {
      maxlen = ln;
      longer = l->name;
    }

    l = l->next;
  }
  if (longer != NULL)
    printf("longer name is : %s\n", longer);

  /* free resources */
  while (head != NULL) {
    l = head;
    head = head->next;
    free(l->name);
    free(l);
  }

  return 0;
}

编译与执行

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra l.c
pi@raspberrypi:/tmp $ cat aze
firstname secondname
anothername
lastname
pi@raspberrypi:/tmp $ ./a.out
Enter the file name: aze
The names in aze file are:
firstname
secondname
anothername
lastname
longer name is : anothername

valgrind

下执行
pi@raspberrypi:/tmp $ valgrind ./a.out
==10132== Memcheck, a memory error detector
==10132== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10132== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10132== Command: ./a.out
==10132== 
Enter the file name: aze
The names in aze file are:
firstname
secondname
anothername
lastname
longer name is : anothername
==10132== 
==10132== HEAP SUMMARY:
==10132==     in use at exit: 0 bytes in 0 blocks
==10132==   total heap usage: 12 allocs, 12 frees, 6,570 bytes allocated
==10132== 
==10132== All heap blocks were freed -- no leaks are possible
==10132== 
==10132== For counts of detected and suppressed errors, rerun with: -v
==10132== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

请注意,链表可以用char*数组替换,使用 realloc 可以在读取名称等时增加其大小

答案 1 :(得分:1)

除了输入格式的详细信息外,在当前解决方案中读取数据并不灵活。继承人比较慷慨的输入内容。将此问题与其他答案结合起来,您就可以了。

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

int main(void) {
    {
        char *cwd = getcwd(NULL, 0);
        printf("FYI, the current working directory of this program is : `%s'\n", cwd);
        free(cwd);
    }
    printf("Enter the file name: ");
    char *filename;
    int scanf_return = scanf("%m[a-zA-Z./]", &filename);
    if (scanf_return != 1) {
        if (errno != 0) {
            perror("scanf");
        } else {
            fprintf(stderr, "%s\n",
                    "Sorry, unable to read file name. "
                    "Only 'a'...'z', 'A'...'Z', '.' (period) "
                    "and '/' (slash) allowed in the name.");
        }
        return EXIT_FAILURE;
    }
    FILE *f = fopen(filename, "r");
    if (f == NULL) {
        perror(filename);
        free(filename);
        return EXIT_FAILURE;
    }
    printf("The contents of `%s' file are:\n", filename);
    free(filename);
    filename = NULL;

    size_t line_sz = 0u;
    char *line = NULL;
    int nread;
    errno = 0;
    while ((nread = getline(&line, &line_sz, f)) != -1) {
        // If we reached the EOF then there might not be a newline character
        if (line[nread - 1] != '\n') {
            nread++;
        }
        printf("`%.*s'\n", nread - 1, line);
    }
    if (errno != 0) {
        perror("getline");
        free(line);
        fclose(f);
        return EXIT_FAILURE;
    }
    free(line);
    fclose(f);
    return EXIT_SUCCESS;
}