我正在学习使用结构,当用C进行一次练习时,这个疑问来找我。 我有这段代码:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#define MAX_STRING 256
#define MAX_CHILD 2000
#define MAX_GIFTS 20
#define MAX_LINE 1024
typedef char String[MAX_STRING];
typedef char Line[MAX_LINE];
typedef struct {
String child_name;
int grade; //integer between 0 and 5
String gift_name;
int price; //price of the gift
} Data;
typedef struct {
String name;
int price;
bool received; //true if the child will get this gift
} Gift;
typedef Gift Gifts[MAX_CHILD];
typedef struct{
String name;
int grade;
Gifts asked; //gifts the child asked for
int n_asked;
} Child;
typedef Child Children[MAX_CHILD];
Data make_data (String line){
Data d;
sscanf(line,"%s %d %s %d", d.child_name, &d.grade, d.gift_name, &d.price);
return d;
}
Child make_child(Data d) {
Child c;
strcpy(c.name, d.child_name);
c.grade = d.grade;
c.n_asked = 0;
return c;
}
Gift make_gift(Data d){
Gift g;
strcpy(g.name, d.gift_name);
g.price = d.price;
g.received = false;
return g;
}
int process(char file_name[]){
Line line;
FILE *f = fopen(file_name, "r");
while(fgets(line, MAX_LINE, f) != NULL){
make_data(line);
}
int fclose (FILE *f);
}
int main(){
process("data.txt");
return 0;
}
所以这个程序收到这种格式的文件文本:
John 4 Bike 200
Alice 3 Computer 800
Alice 3 Candy 10
Mike 5 Skate 100
并在函数进程中构建数据。
问题是,我想将所有子项存储在数组Children []中并打印它(打印所有数组或类似于Children [0],Children [1]等)。我尝试了一些方法但没有成功......因为数组是Child类型而不是char *。即使我只是Children cs;
,我也会遇到分段错误。有没有办法可以实现这个目标?
我的第二个问题是,最初我有#define MAX_CHILD 20000
,当我尝试编译时,我得到一个错误说&#34;数组'儿童'的大小太大&#34;。为什么会这样?我认为它不会发生在礼物上,但会发生在儿童身上,因为结构Child在成员上有一个礼物类型,这意味着它需要更多的空间。
任何帮助表示感谢。
答案 0 :(得分:0)
the use of the typedef's (and so on)
instead of just writing the code out where it is needed
is unneeded (and distracting) and mis-leading and
makes the code much more difficult to follow.
This function:
Data make_data (String line)
{
Data d;
sscanf(line,"%s %d %s %d", d.child_name, &d.grade, d.gift_name, &d.price);
return d;
}
has several problems:
1) the parameter list will cause the compiler to 'set aside' enough room
for the String struct,
invoke a memcpy() to copy the String struct
to that 'set aside' memory from the callers' memory
Then copy the 'set aside' memory to the called functions' stack
That 'set aside' memory will never be used for anything else
The stack will be cluttered with the contents of the String struct
until the function returns
such activity is a real 'bear' to debug
2) the returned value from sscanf() needs to be checked
to assure that all 4 conversion operations were successful
3) the function return is a instance of the Data struct.
This will cause the compiler to 'set aside' enough room
for the Data struct.
that 'set aside' memory will never be used for anything else
invoke a memcpy() to copy the Data struct from the stack
to the 'set aside' memory
then perform the return from the function
then the compiler will cause the caller to
invoke memcpy() to copy the Data struct
from the 'set aside' memory to the caller's Data struct area.
such activity is a real 'bear' to debug.
The function should be written more like this:
int make_data (String *pLine, Data* pData)
{
int returnValue = 1; // initialize to indicate function successful
if( 4 != sscanf(pLine," %s %d %s %d",
pData->child_name,
&pData->grade,
pData->gift_name,
&pData->price) )
{ // then sscanf failed
perror( "sscanf failed for Line" );
returnValue = 0; // indicate to caller that function failed
} // end if
return( returnValue );
} // end function: make_data
and the caller(s) of this function should be adjusted accordingly
the make_gift() function has the same passed parameter
and returned parameter problems.
答案 1 :(得分:0)
问题是,我想将所有子节点存储在数组中 儿童[]并打印它(打印所有数组或只是一些东西 类似于儿童[0],儿童[1]等。
存储:
static Children cs;
size_t nc = 0; // number of children
while (fgets(line, MAX_LINE, f))
{
#include <search.h>
Data d = make_data(line);
Child c = make_child(d);
Child *cp = lsearch(&c, cs, &nc, sizeof c, (int (*)())strcmp);
cp->asked[cp->n_asked++] = make_gift(d);
}
打印:
int i, j;
for (i = 0; i < nc; ++i)
{
printf("%s (grade %d) asked for %d:\n",
cs[i].name, cs[i].grade, cs[i].n_asked);
for (j = 0; j < cs[i].n_asked; ++j)
printf("\t%s\t%d\n", cs[i].asked[j].name, cs[i].asked[j].price);
}
(我们不能简单地打印聚合类型对象 - 我们必须打印单个元素。)