我是C的新手;请尽量帮助我。
我得到main()
指向文件的参数,
所以在for循环中我fopen()
他们想要将它们发送到一个函数
读取它们内部的文本信息并将其放入char变量中。
以下是一个示例文件:
#station name Station Name : A1 #octan of fuel 6.54 full service price 6.40 self service Octan95,6.54,6.40 Octan98,8.30,8.15 #carNum,Octan,numOfLiters,Kind of service 22-334-55,95,31.3,FullService 22-334-55,95,31.3,SelfService 11-444-77,95,12,FullService 11-444-77,95,44.1,FullService 11-444-77,95,11.22,SelfService
文本的字段用逗号分隔,我需要将这些逗号之间的信息添加到变量中。
阅读这些文本文件的最佳方式或功能是什么?
我还应该在每一行之后预期'\n'
,还是在没有新行字符的情况下将其作为一个大char[]
流?
答案 0 :(得分:0)
逐行读取文件 使用strtok函数来获取逗号之间的所有内容
答案 1 :(得分:0)
逐行读取文件并使用带有返回值的sscanf来获取逗号之间的所有内容
答案 2 :(得分:0)
以后大约200行代码......并使用稍微修改过的数据文件版本(请注意原文中的第二个标题行缺少所有逗号):
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
** Example data:
**
** #station name
** Station Name : A1
** #octan of fuel,full service price,self service price
** Octan95,6.54,6.40
** Octan98,8.30,8.15
** #carNum,Octan,numOfLiters,Kind of service
** 22-334-55,95,31.3,FullService
** 22-334-55,95,31.3,SelfService
** 11-444-77,95,12,FullService
** 11-444-77,95,44.1,FullService
** 11-444-77,95,11.22,SelfService
**
** - Header lines are followed by one or more data lines
** - Number of fields in header matches number of fields in each data line
** - Commas separate fields and do not appear within fields (not full CSV)
*/
/* A Line structure holds the fields for one line */
typedef struct Line
{
size_t num_fields;
char **fields;
} Line;
/* A Section structure holds the header line and the set of data lines */
typedef struct Section
{
size_t num_rows;
size_t num_cols;
Line header;
Line *lines; /* Array of lines - num_rows entries in array */
} Section;
/* An Info structure holds all the sections for a single file */
typedef struct Info
{
size_t num_sections;
Section *sections;
} Info;
static void err_exit(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
exit(1);
}
static void *xrealloc(void *old_data, size_t nbytes)
{
void *new_data = realloc(old_data, nbytes);
if (new_data == 0)
err_exit("Out of memory!\n");
return new_data;
}
static void *xmalloc(size_t nbytes)
{
void *new_data = malloc(nbytes);
if (new_data == 0)
err_exit("Out of memory!\n");
return new_data;
}
/* Duplicate a string of given length (excluding NUL) */
static char *xstrndup(const char *str, size_t len)
{
char *new_data = xmalloc(len+1);
memmove(new_data, str, len);
new_data[len] = '\0';
return new_data;
}
static void dump_line(FILE *fp, const Line * const line)
{
size_t i;
const char *pad = "";
for (i = 0; i < line->num_fields; i++)
{
fprintf(fp, "%s%*s", pad, 1, line->fields[i]);
pad = " ";
}
fputc('\n', fp);
}
static void dump_section(FILE *fp, const char *tag, const Section * const section)
{
if (tag != 0)
fprintf(fp, "Dump Section: %s\n", tag);
fprintf(fp, "Number of columns: %zd\n", section->num_cols);
fprintf(fp, "Number of lines: %zd\n", section->num_rows);
dump_line(fp, §ion->header);
for (size_t i = 0; i < section->num_rows; i++)
dump_line(fp, §ion->lines[i]);
}
static void dump_info(FILE *fp, const char *tag, const Info * const info)
{
size_t i;
fprintf(fp, "Dump Information: %s\n", tag);
fprintf(fp, "Number of sections: %zd\n", info->num_sections);
for (i = 0; i < info->num_sections; i++)
{
char title[20];
snprintf(title, sizeof(title), "%d", i+1);
dump_section(fp, title, &info->sections[i]);
}
fprintf(fp, "End of Information Dump\n");
}
static int num_fields(const char *buffer)
{
size_t posn = 0;
size_t next;
int count = 0;
while ((next = strcspn(buffer + posn, ",\n")) > 0)
{
count++;
if (buffer[posn+next] == '\n')
break;
posn += next + 1;
}
return count;
}
static void set_line(Line *line, int nfields, const char *buffer)
{
size_t posn = 0;
line->num_fields = nfields;
line->fields = xmalloc(nfields * sizeof(*line->fields));
for (int i = 0; i < nfields; i++)
{
size_t next = strcspn(buffer+posn, ",\n");
line->fields[i] = xstrndup(buffer+posn, next);
if (buffer[posn+next] == '\n')
{
if (i != nfields - 1)
err_exit("Internal error: field count mismatch\n");
break;
}
posn += next + 1;
}
}
static int add_section(Info *info, char *buffer)
{
int nfields = num_fields(buffer);
int nsections = info->num_sections + 1;
info->sections = xrealloc(info->sections, nsections * sizeof(*info->sections));
info->num_sections = nsections;
Section *new_section = &info->sections[nsections-1];
new_section->num_cols = nfields;
new_section->num_rows = 0;
set_line(&new_section->header, nfields, buffer);
new_section->lines = 0;
return nfields;
}
/* Beware - very compact code! */
static void add_line_to_section(Section *section, const char *buffer, int nfields)
{
section->lines = xrealloc(section->lines, (section->num_rows + 1) * sizeof(*section->lines));
set_line(§ion->lines[section->num_rows++], nfields, buffer);
}
static int peek(FILE *fp)
{
int c;
if ((c = getc(fp)) != EOF)
ungetc(c, fp);
return c;
}
static void read_info(FILE *fp, Info *info)
{
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp) != 0)
{
if (*buffer != '#')
err_exit("Format error: expected line beginning '#' (got '%.*s')\n",
10, buffer);
int nfields = add_section(info, buffer+1);
int c;
Section *cursect = &info->sections[info->num_sections-1];
while ((c = peek(fp)) != EOF && c != '#')
{
if (fgets(buffer, sizeof(buffer), fp) != 0)
{
int lfields = num_fields(buffer);
if (lfields != nfields)
err_exit("Mismatch in number of fields (got %d, wanted %) at '%*s'\n",
lfields, nfields, 20, buffer);
add_line_to_section(cursect, buffer, nfields);
}
}
}
}
int main(int argc, char **argv)
{
int i;
Info info = { 0, 0 };
for (i = 1; i < argc; i++)
{
FILE *fp;
if ((fp = fopen(argv[i], "r")) != 0)
{
read_info(fp, &info);
dump_info(stdout, "After loop", &info);
}
else
fprintf(stderr, "Failed to open file %s (%s)\n", argv[i], strerror(errno));
}
dump_info(stdout, "End of main loop", &info);
return 0;
}
代码在大多数意义上并不是最佳的 - 它分配了太多的小内存。我也很懒,没有写代码来释放内存。不过,我认为把它作为你的代码不是一个好主意。