[英]Parsing a tab delimited text file in C
so, i saw an older post that showed how to do this, but for some reason it seems it no longer works, my input file consists of a header row, and then 15 rows of input, each with 5 columns, first 2 are strings, the last 3 are ints, i have a struct to store them, and im trying to write the contents into an array of these structs所以,我看到一篇较旧的帖子显示了如何执行此操作,但由于某种原因,它似乎不再有效,我的输入文件由 header 行组成,然后是 15 行输入,每行有 5 列,前 2 行是字符串,最后3个是整数,我有一个结构来存储它们,我试图将内容写入这些结构的数组
FName LName Credits Transactions Modifer
John Doe 83000 2 1
Jane Doe 64000 5 3
I tried我试过了
struct customer cust = { NULL,NULL,0,0,0};
char line[SIZE] = { 0 }, * ptr = NULL;
cust.fName = malloc(15);
cust.lName = malloc(15);
printf("%d\n", &fp);
if (NULL == (fp = fopen("../customers.txt", "r")))
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while (EOF != fscanf(fp, "%s", line))
{
ptr = strtok(line, "\\");
cust.fName = ptr;
printf("%s", ptr);
while (EOF != (ptr = strtok(NULL, "\\")))
{
i++;
printf("%s",ptr);
if (i == 1)
cust.lName = ptr;
else if (i == 2)
cust.miles = atoi(ptr);
else if (i == 3)
cust.years = atoi(ptr);
else if (i == 4)
cust.sequence = atoi(ptr);
}
i = 0;
printf("After Reading: fName:[%s] lName:[%s] miles:[%d] years:[%d]\n", cust.fName, cust.lName, cust.miles, cust.years);
}
For some reason, the printf
within the inner while loop only prints "(null)"
, and errors out when i==2
with the error出于某种原因,内部 while 循环中的
printf
仅打印"(null)"
,并且当i==2
出现错误时出错
File: minkernel\crts\ucrt\inc\corecrt_internal_strtox.h
Line: 1772
Expression: _p != nullptr
I dont have any idea what that error message means, so i dont know what im doing wrong我不知道该错误消息是什么意思,所以我不知道我做错了什么
Also, Craig, do you mind giving an example, im pretty new to using C and am unfamiliar with fgets
另外,克雷格,你介意举个例子吗,我对使用 C 很陌生,我不熟悉 fgets
Okay.好的。 Because your code was a bit far off, I had to refactor it heavily.
因为你的代码有点远,我不得不大量重构它。
Your code was only handling a single customer record.您的代码只处理一个客户记录。 What you need to do is a separate
struct
instance for each line (ie customer).您需要做的是为每一行(即客户)创建一个单独的
struct
实例。 So, we want to use realloc
to enlarge a dynamic array of our struct customer
.因此,我们想使用
realloc
来扩大我们的struct customer
的动态数组。
And, you have allocate memory [on the heap] for each string in a record (ie first and last names).而且,您已经为记录中的每个字符串(即名字和姓氏)分配了 memory [在堆上]。 So, we have to use
strdup
所以,我们必须使用
strdup
Anyway, here's the code:无论如何,这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct customer {
char *fName;
char *lName;
int miles;
int years;
int sequence;
};
int
main(void)
{
FILE *fp;
char buf[1000];
char *cp;
char *bp;
struct customer *list = NULL;
int custcnt = 0;
struct customer *cust;
const char *delim = "\t\n";
int field;
fp = fopen("customers.txt","r");
if (fp == NULL) {
perror("error opening file");
exit(1);
}
while (1) {
cp = fgets(buf,sizeof(buf),fp);
if (cp == NULL)
break;
// increase size of customer list/array by one
list = realloc(list,sizeof(*list) * (custcnt + 1));
if (list == NULL) {
perror("malloc");
exit(1);
}
// point to place for next customer
cust = &list[custcnt];
// advance customer count
++custcnt;
// preclear the new record in case of a line that is malformed (i.e.
// missing some data)
memset(cust,0,sizeof(*cust));
// loop through and store all customer record fields
bp = buf;
for (field = 0; field < 5; ++field) {
cp = strtok(bp,delim);
if (cp == NULL)
break;
bp = NULL;
switch (field) {
case 0:
cust->fName = strdup(cp);
break;
case 1:
cust->lName = strdup(cp);
break;
case 2:
cust->miles = atoi(cp);
break;
case 3:
cust->years = atoi(cp);
break;
case 4:
cust->sequence = atoi(cp);
break;
}
}
printf("After Reading: fName:[%s] lName:[%s] miles:[%d] years:[%d]\n",
cust->fName, cust->lName, cust->miles, cust->years);
}
fclose(fp);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.