将制表符分隔的文件读取到C中的结构
我有一个带有制表符分隔数据的文件。我想把每一行读成一个结构。我有一个将数据读取到char缓冲区的代码。但是我想把数据加载到一个结构中 这是我的样本数据 empname1\t001\t35\tcity1 empname2\t002\t35\tcity2 我的结构定义将制表符分隔的文件读取到C中的结构,c,file,input,struct,tab-delimited-text,C,File,Input,Struct,Tab Delimited Text,我有一个带有制表符分隔数据的文件。我想把每一行读成一个结构。我有一个将数据读取到char缓冲区的代码。但是我想把数据加载到一个结构中 这是我的样本数据 empname1\t001\t35\tcity1 empname2\t002\t35\tcity2 我的结构定义 struct employee { char *empname; char *empid; int age; char *addr; }; 我的示例程序将数据读取到chararraybuffer char buff
struct employee
{
char *empname;
char *empid;
int age;
char *addr;
};
我的示例程序将数据读取到char
arraybuffer
char buffer[BUF_SIZE]; /* Character buffer */
input_fd = open (fSource, O_RDONLY);
if (input_fd == -1) {
perror ("open");
return 2;
}
while((ret_in = read (input_fd, &buffer, BUF_SIZE)) > 0){
// Do Some Process
}
这里我想将内容加载到结构变量,而不是字符缓冲区。我怎样才能做到这一点呢?嗯,一个可能的解决办法是
选项卡
在您的情况下]使用标记化输入缓冲区fgets()
读取并存储尾部的\n
。
2.请仔细检查如何使用strtok()。输入字符串应该是可变的。
3.在使用指针之前将内存分配给指针。在我看来,使用静态分配的数组作为struct employee
成员变量。
您可以使用fscanf功能。以流形式打开一个文件,然后使用fscanf从该文件获取输入
int fscanf(FILE *stream, const char *format, ...);
FILE *fp=fopen(fsource,"r+");
struct employee detail;
fscanf(fp,"%s %s %d %s",detail.empname,detail.empid,&detail.age,detail.addr);
确保为变量分配内存
或者您可以使用
strok
功能。那时候你必须使用sscanf功能。我想这可能就是你想要的
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
struct employee
{
char *empname;
char *empid;
int age;
char *addr;
};
int readEmploee(char *line, struct employee *employee)
{
char *token;
char *saveptr;
char *endptr;
if ((employee == NULL) || (line == NULL))
return 0;
token = strtok_r(line, "\t", &saveptr);
if (token == NULL)
return 0;
employee->empname = strdup(token);
token = strtok_r(NULL, "\t", &saveptr);
if (token == NULL)
return 0;
employee->empid = strdup(token);
token = strtok_r(NULL, "\t", &saveptr);
if (token == NULL)
return 0;
employee->age = strtol(token, &endptr, 10);
if (*endptr != '\0')
return 0;
token = strtok_r(NULL, "\t", &saveptr);
if (token == NULL)
return 0;
employee->addr = strdup(token);
return 1;
}
char *mygetline(int fd)
{
char *line;
size_t length;
size_t count;
char character;
line = malloc(128);
if (line == NULL)
return NULL;
length = 0;
count = 1;
do
{
if (read(fd, &character, 1) != 1) /* end of file probably reached */
{
free(line);
return NULL;
}
else if (character != '\n')
{
if (length > 128 * count)
{
char *temp;
temp = realloc(line, 128 * count);
if (temp == NULL)
{
free(line);
return NULL;
}
line = temp;
count += 1;
}
line[length++] = character;
}
} while (character != '\n');
line[length] = 0;
return line;
}
struct employee *readFile(const char *const fSource, size_t *count)
{
struct employee *employees;
int employeeCount;
int input_fd;
char *line;
if ((count == NULL) || (fSource == NULL))
return NULL;
*count = 0;
employees = NULL;
employeeCount = 0;
input_fd = open (fSource, O_RDONLY);
if (input_fd == -1)
{
perror ("open");
return NULL;
}
while ((line = mygetline(input_fd)) != NULL)
{
struct employee employee;
if (readEmploee(line, &employee) != 0)
{
struct employee *temp;
temp = realloc(employees, (1 + employeeCount) * sizeof(struct employee));
if (temp != NULL)
employees = temp;
employees[employeeCount++] = employee;
}
free(line);
}
*count = employeeCount;
return employees;
}
int
main()
{
size_t count;
size_t index;
struct employee *employees;
employees = readFile("somesamplefile.txt", &count);
if (employees == NULL)
return 1;
for (index = 0 ; index < count ; index++)
{
struct employee current;
current = employees[index];
fprintf(stderr, "%s, %s, %d, %s\n", current.empname, current.empid, current.age, current.addr);
if (current.empname != NULL)
free(current.empname);
if (current.empid != NULL)
free(current.empid);
if (current.addr != NULL)
free(current.addr);
}
free(employees);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构雇员
{
字符*empname;
char*empid;
智力年龄;
char*addr;
};
int reademployee(字符*行,结构雇员*雇员)
{
字符*令牌;
char*saveptr;
char*endptr;
if((employee==NULL)| |(line==NULL))
返回0;
令牌=strtok_r(第“\t”行和saveptr);
if(标记==NULL)
返回0;
employee->empname=strdup(令牌);
令牌=strtok_r(NULL、\t、&saveptr);
if(标记==NULL)
返回0;
employee->empid=strdup(令牌);
令牌=strtok_r(NULL、\t、&saveptr);
if(标记==NULL)
返回0;
员工->年龄=strtol(令牌和endptr,10);
如果(*endptr!='\0')
返回0;
令牌=strtok_r(NULL、\t、&saveptr);
if(标记==NULL)
返回0;
员工->地址=strdup(令牌);
返回1;
}
字符*mygetline(int-fd)
{
字符*行;
尺寸与长度;
大小/数量;
字符;
直线=malloc(128);
如果(行==NULL)
返回NULL;
长度=0;
计数=1;
做
{
如果(读取(fd,&字符,1)!=1)/*可能已到达文件结尾*/
{
自由线;
返回NULL;
}
else if(字符!='\n')
{
如果(长度>128*计数)
{
字符*温度;
temp=realloc(行,128*计数);
if(temp==NULL)
{
自由线;
返回NULL;
}
线路=温度;
计数+=1;
}
行[长度++]=字符;
}
}while(字符!='\n');
行[长度]=0;
回流线;
}
结构employee*读取文件(常量字符*常量源,大小*计数)
{
结构雇员*雇员;
国际雇员人数;
int-input_-fd;
字符*行;
if((count==NULL)| |(fSource==NULL))
返回NULL;
*计数=0;
employees=NULL;
雇员人数=0;
input_fd=打开(仅限fSource、O_rdu);
如果(输入_fd==-1)
{
佩罗(“公开”);
返回NULL;
}
while((line=mygetline(input_fd))!=NULL)
{
结构员工;
如果(读员工(行和员工)!=0)
{
结构雇员*临时雇员;
temp=realloc(员工,(1+员工人数)*sizeof(结构员工));
如果(温度!=NULL)
雇员=临时工;
员工[employeeCount++]=员工;
}
自由线;
}
*计数=雇员计数;
返回员工;
}
int
main()
{
大小/数量;
尺寸指数;
结构雇员*雇员;
employees=readFile(“somesamplefile.txt”、&count);
if(employees==NULL)
返回1;
对于(索引=0;索引<计数;索引++)
{
结构员工当前;
当前=员工[索引];
fprintf(stderr,“%s,%s,%d,%s\n”,current.empname,current.empid,current.age,current.addr);
if(current.empname!=NULL)
自由(当前.empname);
如果(current.empid!=NULL)
自由(当前的empid);
如果(current.addr!=NULL)
自由(当前地址);
}
免费(员工);
返回0;
}
您可以使用fscanf
读取文件中的每一行,使用strtok
标记读取的行。因为您的结构成员是指针,所以适当地分配内存 下面的最小代码正是您想要的
#define SIZE 50
FILE *fp = NULL;
int i = 0;
struct employee var = {NULL, NULL, 0, NULL};
char line[SIZE] = {0}, *ptr = NULL;
/* 1. Open file for Reading */
if (NULL == (fp = fopen("file.txt","r")))
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
工作演示: 这里需要注意的几点:
i
),这就可以保证工作正常李>
strtok(行“\\”)
,第二个参数只是转义(第一个\
)实际的\
字符OP的澄清: 在您的结构定义中,第三个成员是
int
,但是您试图将t35
读入其中(这是一个字符串)。因此
var.age=atoi(ptr)代码>将为您提供0
您可以更改结构定义,将第三个成员设置为char*
,并像其他成员一样分配内存
或更改文件内容,确保
/* 2. Allocate Memory */
var.empname = malloc(SIZE);
var.empid = malloc(SIZE);
var.addr = malloc(SIZE);
/* 3. Read each line from the file */
while (EOF != fscanf(fp, "%s", line))
{
/* 4. Tokenise the read line, using "\" delimiter*/
ptr = strtok(line, "\\");
var.empname = ptr;
while (NULL != (ptr = strtok(NULL, "\\")))
{
i++;
/* 5. Store the tokens as per structure members , where (i==0) is first member and so on.. */
if(i == 1)
var.empid = ptr;
else if(i == 2)
var.age = atoi(ptr);
else if (i == 3)
var.addr = ptr;
}
i = 0; /* Reset value of i */
printf("After Reading: Name:[%s] Id:[%s] Age:[%d] Addr:[%s]\n", var.empname, var.empid, var.age, var.addr);
}