gpt4 book ai didi

c - 将数据分配给二维数组并显示 C

转载 作者:太空宇宙 更新时间:2023-11-04 03:23:51 25 4
gpt4 key购买 nike

我正在编写一个程序,它将打开 csv 文件并将数据保存到 3D 数组。大多数代码工作得很好,但我在将记录分配给二维数组时遇到问题。

代码如下:

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

#define FILE_MODE "r"
/*
Explode string with given token and assign result to list variable
*/
int explode(const char *src, const char *tokens, char ***list, size_t *len)
{
if(src == NULL || list == NULL || len == NULL) {
return 0;
}

char *str, *copy, **_list = NULL, **tmp;
*list = NULL;
*len = 0;

copy = strdup(src);
if(copy == NULL)
return 1;

str = strtok(copy, tokens);
if(str == NULL) {
goto free_and_exit;
}

_list = realloc(NULL, sizeof *_list);
if(_list == NULL) {
goto free_and_exit;
}

_list[*len] = strdup(str);
if(_list[*len] == NULL)
goto free_and_exit;
(*len)++;

while((str = strtok(NULL, tokens)))
{
tmp = realloc(_list, (sizeof *_list) * (*len + 1));
if(tmp == NULL)
goto free_and_exit;

_list = tmp;

_list[*len] = strdup(str);
if(_list[*len] == NULL)
goto free_and_exit;
(*len)++;
}

free_and_exit:
*list = _list;
free(copy);

return 2;
}

/*
Exploding lines in CSV file
*/
const char* getfield(char* line, int num)
{
const char* tok;
for (tok = strtok(line, ";");
tok && *tok;
tok = strtok(NULL, ";\n"))
{
if (!--num)
return tok;
}
return NULL;
}


int main()
{
FILE *stream;
char fileName[256], table[256], line[256],
**list, **columns, **data;
size_t length;

printf("Witaj uzytkowniku! Podaj nazwe pliku z rozszerzeniem .csv. \n");
scanf("%s", fileName);

explode(fileName, ".", &list, &length);
strcpy(table, list[0]);

stream = fopen("file.csv", FILE_MODE); // not to write path every single time

if (stream == NULL) {
printf("Nie moge otworzyc pliku %s do odczytu!\n", fileName);
exit(1);
}

fgets(line, sizeof line, stream);
explode(line, ";", &columns, &length);

int recordNumber = 0
,columnNumber = 0;

while (fgets(line, sizeof line, stream))
{
char* tmp = strdup(line);
if (getfield(tmp, recordNumber) != NULL) {
columnNumber++;
}

recordNumber++;
free(tmp);
}

fseek(stream, 0, SEEK_SET); // Go to beginning of file
fgets(line, 1024, stream);

int i = 0 // Number of records
,h = 0; // number of columns

char **records[recordNumber][columnNumber];
length = 0;
char *tmp[recordNumber];

// Here I get number of lines and columns in csv file to make 3D array??
while (fgets(line, sizeof line, stream) && i < recordNumber)
{
tmp[i] = strdup(line);
explode(tmp[i], ";", &data, &length);

for (h = 0; h < columnNumber; h++)
{
memcpy(records[i][h], data[h], sizeof(data[h]));
}

i++;
}

for (i = 0; i < recordNumber; i++)
{
for (h = 0; h < columnNumber; h++)
{
printf("%s ", records[i][h][0]);
}
printf("\n");
}

fclose(stream);
return EXIT_SUCCESS;
}

问题开始了,当我尝试做一个循环,将数据分配给数组时:

 while (fgets(line, sizeof line, stream) && i < recordNumber)
{
tmp[i] = strdup(line);
explode(tmp[i], ";", &data, &length);

for (h = 0; h < columnNumber; h++)
{
memcpy(records[i][h], data[h], sizeof(data[h]));
}

i++;
}

我尝试使用 memcpy 和 strcpy,但没有一个能正常工作 - 我很确定。当代码转到这些行时,出现错误:段错误(核心转储)。我想要实现的是用 csv 文件中的数据填充这个数组并打印它。

感谢您的帮助! :)


编辑:

爆炸功能不是我的。可能,我在 stackoverflow 的某个地方找到了它。

当涉及到代码时,稍加改动就可以了

    char records[recordNumber][columnNumber][1024];
length = 0;
char *tmp[recordNumber];

while (fgets(line, sizeof line, stream) && i < recordNumber)
{
tmp[i] = strdup(line);
explode(tmp[i], ";", &data, &length);

for (h = 0; h < columnNumber; h++)
{
strcpy(records[i][h], data[h]);
}

i++;
}

最佳答案

使用fgets 读取文件的每一行。 strpbrk 可用于查找分隔符。可以使用两个指针来获取定界符之间的字符数。然后分配内存,使用memcpy将字段复制到分配的内存中。

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

char ***strpdlm ( char *pdelim, int skip);
char ***freedlm ( char ***ppp);

int main()
{
char ***expld = NULL;
int line = 0;
int field = 0;

//last argument of 1 is skip consecutive delimiters. 0 do not skip
expld = strpdlm ( ";\n", 1);// delimiters semicolon and newline
//print each extracted string
line = 0;
if ( expld) {//not null
while ( expld[line]) {//not null
field = 0;
printf ( "\nfields for line %d\n", line);
while ( expld[line][field]) {//not null
printf ( "expld[%d][%d] %s\n", line, field, expld[line][field]);
field++;
}
line++;
}
}
//free memory and set NULL
expld = freedlm ( expld);

return 0;
}

char ***freedlm ( char ***ppp) {
size_t each = 0;
size_t item = 0;

if ( ppp) {
while ( ppp[each]) {
item = 0;
while ( ppp[each][item]) {
free ( ppp[each][item]);
item++;
}
free ( ppp[each]);
each++;
}
free ( ppp);
}

return NULL;
}

char ***strpdlm ( char *pdelim, int skip) {
char ***xpld = NULL;
char ***temprecord = NULL;
char **tempfield = NULL;
char *pnt = NULL;
char *cur = NULL;
char line[1024] = "";
int span = 0;
int len = 0;
int record = 0;
int field = 0;
FILE *pf = NULL;

if ( ( pf = fopen ( "file.csv", "r")) == NULL) {
perror ( "could not open \"file.csv\"");
return NULL;
}

if ( pdelim) {
while ( fgets ( line, sizeof line, pf)) {
//make sure each line ends with \n
len = strcspn ( line, "\n");
if ( len + 1 < sizeof line) {
line[len] = '\n';
line[len + 1] = '\0';
}
//allocate record + 2 pointers
if ( ( temprecord = realloc ( xpld, ( record + 2) * sizeof ( *xpld))) == NULL) {
fprintf ( stderr, "problem realloc records\n");
fclose ( pf);
return xpld;
}
xpld = temprecord;
xpld[record] = NULL;

field = 0;
cur = line;//cur points to line
while ( ( pnt = strpbrk ( cur, pdelim))) {
if ( pnt != cur || !skip) {
if ( ( tempfield = realloc ( xpld[record], ( field + 2) * sizeof ( **xpld))) == NULL) {
fprintf ( stderr, "problem realloc fields\n");
fclose ( pf);
return xpld;
}
xpld[record] = tempfield;
xpld[record][field] = NULL;

if ( pnt) {
span = pnt - cur;
}
else {
span = strlen ( cur);
}

if ( ( xpld[record][field] = malloc ( span + 1)) == NULL) {
fprintf ( stderr, "problem malloc\n");
fclose ( pf);
return xpld;
}
memcpy ( xpld[record][field], cur, span);
xpld[record][field][span] = '\0';
field++;
xpld[record][field] = NULL;//sentinel NULL
}
cur = pnt + 1;//set cur to point to next field
}
record++;
xpld[record] = NULL;//sentinel NULL
}
}
fclose ( pf);
return xpld;
}

关于c - 将数据分配给二维数组并显示 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42873657/

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