我有一个带制表符分隔数据的文件。我想把每一行都读成一个结构。我有一个代码来读取数据到char缓冲区。但我想将数据加载到Structure中。
这是我的样本数据。
empname1 \ t001 \ t35 \ tcity1
empname2 \ T002 \ T35 \ tcity2
我的结构定义。
struct employee
{
char *empname;
char *empid;
int age;
char *addr;
};
我的示例程序,用于将数据读取到char
数组buffer
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
}
这里我想将内容加载到结构变量而不是字符缓冲区。我怎么能做到这一点?
答案 0 :(得分:7)
嗯,一个可能的解决方案可能是
使用fgets()
从文件中读取完整的一行。
使用strtok()
根据您所需的分隔符[tab
}对输入缓冲区进行标记。
将内存(malloc()
/ realloc()
)分配给结构的指针变量。
将标记化输入复制到成员变量中。
注意:
1. fgets()
读取并存储尾随\n
。
2.请仔细检查如何使用strtok()
。输入字符串应该是可变的。
3.在使用之前将内存分配给指针。 IMO,使用静态分配的数组作为struct employee
成员变量。
功能
答案 1 :(得分:2)
您可以使用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);
确保为变量分配内存。
否则您可以使用strtok
功能。那个时候你必须使用sscanf函数。
答案 2 :(得分:2)
您可以使用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);
}
/* 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);
}
这里有几点需要注意:
i
的操作),这就可以保证有效。 strtok(line, "\\");
,第二个参数只是转义(第一个\
)实际的\
字符。OP的澄清:
在您的结构定义中,第三个成员是int
,但是您尝试将t35
读入其中(这是一个字符串< / em>的)。
因此var.age = atoi(ptr);
将为您提供0
,
您可以更改结构定义,将第三个成员设为char *
并像其他成员一样分配内存。
或更改文件内容,确保int
作为第三个值。
答案 3 :(得分:1)
我认为这可能就是你要找的东西
#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;
}