gpt4 book ai didi

使用结构在 C 中输入 CSV 文件

转载 作者:太空宇宙 更新时间:2023-11-04 02:46:30 24 4
gpt4 key购买 nike

我想逐行打印 .csv 文件中的数据,这些数据由 comma 定界符分隔。
此代码打印垃圾值。

enum gender{ M, F };

struct student{
int stud_no;
enum gender stud_gen;
char stud_name[100];
int stud_marks;
};

void main()
{
struct student s[60];
int i=0,j,roll_no,marks,k,select;
FILE *input;
FILE *output;

struct student temp;


input=fopen("Internal test 1 Marks MCA SEM 1 oct 2014 - CS 101.csv","r");
output=fopen("out.txt","a");

if (input == NULL) {
printf("Error opening file...!!!");

}

while(fscanf(input,"%d,%c,%100[^,],%d", &s[i].stud_no,&s[i].stud_gen,&s[i].stud_name,&s[i].stud_marks)!=EOF)
{

printf("\n%d,%c,%s,%d", s[i].stud_no,s[i].stud_gen,s[i].stud_name,s[i].stud_marks);
i++;
}

}

我还尝试了以下代码:Read .CSV file in C但它只打印第 n 字段。我想逐行显示所有字段。

这是我的示例输入。
1401,F,费尔南德斯·苏珊娜,13
1402,M,PARSEKAR VIPUL VILAS,14
1403,M,塞奎拉·克莱顿·迪奥戈,8
1404,男,费尔南德斯·格伦,17
1405,F,CHANDRAVARKAR TANUSHREE ROHIT,15

最佳答案

虽然有很多方法可以将任何行解析为组件,但真正可以增加理解的一种方法是使用 startend指向标识 commas 的每一行的指针,将它们替换为 null-terminators (i.e. '\0' or just 0) , 读取字段,恢复逗号并移动到下一个字段。这只是strtok的手动申请.下面的例子就是这样做的,这样你就可以看到发生了什么。当然,您可以替换使用 startend指针(分别为 sp & p )和 strtok .

通读代码,如果您有任何问题,请告诉我:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* maximum number of student to initially allocate */
#define MAXS 256

enum gender { M, F };

typedef struct { /* create typedef to struct */
int stud_no;
enum gender stud_gen;
char *stud_name;
int stud_marks;
} student;

int main (int argc, char *argv[]) {

if (argc < 2) {
printf ("filename.csv please...\n");
return 1;
}

char *line = NULL; /* pointer to use with getline () */
ssize_t read = 0; /* characters read by getline () */
size_t n = 0; /* number of bytes to allocate */
student **students = NULL; /* ptr to array of stuct student */
char *sp = NULL; /* start pointer for parsing line */
char *p = NULL; /* end pointer to use parsing line */
int field = 0; /* counter for field in line */
int cnt = 0; /* counter for number allocated */
int it = 0; /* simple iterator variable */

FILE *fp;
fp = fopen (argv[1], "r"); /* open file , read only */
if (!fp) {
fprintf (stderr, "failed to open file for reading\n");
return 1;
}

students = calloc (MAXS, sizeof (*students)); /* allocate 256 ptrs set to NULL */

/* read each line in input file preserving 1 pointer as sentinel NULL */
while (cnt < MAXS-1 && (read = getline (&line, &n, fp)) != -1) {

sp = p = line; /* set start ptr and ptr to beginning of line */
field = 0; /* set/reset field to 0 */

students[cnt] = malloc (sizeof (**students)); /* alloc each stuct with malloc */

while (*p) /* for each character in line */
{
if (*p == ',') /* if ',' end of field found */
{
*p = 0; /* set as null-term char (temp) */

if (field == 0) students[cnt]->stud_no = atoi (sp);
if (field == 1) {
if (*sp == 'M') {
students[cnt]->stud_gen = 0;
} else {
students[cnt]->stud_gen = 1;
}
}
if (field == 2) students[cnt]->stud_name = strdup (sp); /* strdup allocates for you */

*p = ','; /* replace with original ',' */
sp = p + 1; /* set new start ptr start pos */
field++; /* update field count */
}
p++; /* increment pointer p */
}
students[cnt]->stud_marks = atoi (sp); /* read stud_marks (sp alread set to begin) */

cnt++; /* increment students count */
}

fclose (fp); /* close file stream */

if (line) /* free memory allocated by getline */
free (line);

/* iterate over all students and print */
printf ("\nThe students in the class are:\n\n");
while (students[it])
{
printf (" %d %c %-30s %d\n",
students[it]->stud_no, (students[it]->stud_gen) ? 'F' : 'M', students[it]->stud_name, students[it]->stud_marks);
it++;
}
printf ("\n");

/* free memory allocated to struct */
it = 0;
while (students[it])
{
if (students[it]->stud_name)
free (students[it]->stud_name);
free (students[it]);
it++;
}
if (students)
free (students);

return 0;
}

(注意:在循环中添加条件 cnt < MAXS-1 以在 students NULL 中保留至少一个指针作为允许迭代的哨兵。)

输入:

$ cat dat/people.dat
1401,F,FERNANDES SUZANNA ,13
1402,M,PARSEKAR VIPUL VILAS,14
1403,M,SEQUEIRA CLAYTON DIOGO,8
1404,M,FERNANDES GLENN ,17
1405,F,CHANDRAVARKAR TANUSHREE ROHIT,15

输出:

$./bin/stud_struct dat/people.dat

The students in the class are:

1401 F FERNANDES SUZANNA 13
1402 M PARSEKAR VIPUL VILAS 14
1403 M SEQUEIRA CLAYTON DIOGO 8
1404 M FERNANDES GLENN 17
1405 F CHANDRAVARKAR TANUSHREE ROHIT 15

valgrind 内存检查:

我稍微更新了代码以确保释放所有分配的内存以防止任何内存泄漏。简单的事情,比如为 line 自动分配内存通过 getline或者未能关闭文件流可能会导致小的内存泄漏。下面是 valgrind内存检查确认。

valgrind ./bin/stud_struct dat/people.dat
==11780== Memcheck, a memory error detector
==11780== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==11780== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==11780== Command: ./bin/stud_struct dat/people.dat
==11780==

The students in the class are:

1401 F FERNANDES SUZANNA 13
1402 M PARSEKAR VIPUL VILAS 14
1403 M SEQUEIRA CLAYTON DIOGO 8
1404 M FERNANDES GLENN 17
1405 F CHANDRAVARKAR TANUSHREE ROHIT 15

==11780==
==11780== HEAP SUMMARY:
==11780== in use at exit: 0 bytes in 0 blocks
==11780== total heap usage: 13 allocs, 13 frees, 2,966 bytes allocated
==11780==
==11780== All heap blocks were freed -- no leaks are possible
==11780==
==11780== For counts of detected and suppressed errors, rerun with: -v
==11780== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

关于使用结构在 C 中输入 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26695399/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com