我的程序的想法是从文件(在这种情况下,文件包含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;
}
答案 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;
}