C 学习结构及其领域的算术

C 学习结构及其领域的算术,c,struct,scanf,C,Struct,Scanf,我现在正在学习结构,它们在我的头脑中是有意义的,但我很难与它们一起工作。我正在使用重定向的标准输入读取文件(“您正在使用结构中未定义成员的垃圾值覆盖*time[j]中的值。请将收集的输入分配到结构中。*time[j]=arrivals.time;应该是arrivals.time=*time[j]; 变量a被声明为int*a,因此它没有成员计数和时间。语句scanf(“%i%i”,a->time,a->count);将抛出语法错误 一种更干净的跟踪方法是声明一个arrival\u struct数组

我现在正在学习结构,它们在我的头脑中是有意义的,但我很难与它们一起工作。我正在使用重定向的标准输入读取文件(“您正在使用结构中未定义成员的垃圾值覆盖
*time[j]
中的值。请将收集的输入分配到结构中。
*time[j]=arrivals.time;
应该是
arrivals.time=*time[j];

变量
a
被声明为
int*a
,因此它没有成员计数和时间。语句
scanf(“%i%i”,a->time,a->count);
将抛出语法错误

一种更干净的跟踪方法是声明一个
arrival\u struct
数组,并在收集输入时定义结构

struct arrrival_struct arrivals[10];

while(...) {
scanf("%d%d", &arrivals[j].time, &arrivals[j].count);
totalPassenger += arrivals[j].count;
j++;
}
编辑


如果一个输入失败,while循环体将不会执行。您可以检查循环外部的错误。

一般来说,我们会这样做。我不喜欢
scanf
输入,但这是另一个主题。错误的输入不会被处理,因为我不会修复
scanf
输入处理

/* dynamically allocated array of structs */
struct arrival_struct *arrivals = NULL;
size_t narrivals = 0; /* number of elements used */
size_t aarraivals = 0; /* number of elements allocated */

while (...)
{
    if (narrivals == aarrivals) {
        /* If we're out of space in the array, double the size. Initial size is 16 */
        arrivals = realloc(arrivals,
            sizeof(*arrivals) * (
                aarrivals = (aarrivals == 0) ? 16 : (aarrivals << 1)
            )
        );
    }
    /* read input */
    scanf("%d", &arrivals[narrivals].time);
    scanf("%d", &arrivals[narrivals].count);
    // ...
    ++narrivals; /* one more usable element in array */
}
/*动态分配的结构数组*/
结构到达\结构*到达=空;
大小\u t=0;/*使用的元素数*/
大小\u t aarraivals=0;/*分配的元素数*/
而(…)
{
如果(NAR竞争对手==AAR竞争对手){
/*如果数组中的空间不足,请将大小加倍。初始大小为16*/
到达=realloc(到达,
sizeof(*抵达人数)*(

AAR竞争对手=(AAR竞争对手==0)?16:(AAR竞争对手虽然你已经有了一个很好的答案,但在你试图理解结构的使用时,你可能错过了它们的大部分好处和用途

struct arrival_struct {
    int time;       // time of arrival
    int count;      // number of passengers/seats arriving
};
然后,您可以只声明一个struct数组来存储从文件的每一行读取的每个组件,并省去过多的附加变量。例如,您可以简单地声明:

 #define MAXS 10     /* if you need a constant, #define one (or more) */
 ...
    struct arrival_struct arrivals[MAXS] = {{ .time = 0 }};
它将声明一个数组
10 struct arrival\u struct
,并将所有值初始化为零

然后,与其冒着落入
scanf
的许多陷阱的风险,不如使用面向行的输入函数(如
fgets
(或POSIX
getline
)一次读取一行数据然后将缓冲区中填充的信息解析为所需的值。这样,输入流中剩余的内容不取决于转换说明符用户或是否发生匹配失败

只需声明一个足够大小的字符缓冲区来容纳每一行(不要忽略缓冲区大小!),并将每一行读入一个缓冲区。然后使用
sscanf
解析该行所需的值,例如

#define MAXC 1024
...
    size_t n = 0;
    char buf[MAXC];

    /* while array space remains, read each line from file into struct */
    while (n < MAXS && fgets (buf, sizeof buf, stdin))
        if (sscanf (buf, "%d %d", &arrivals[n].time, &arrivals[n].count) == 2)
            n++;
#定义MAXC 1024
...
尺寸n=0;
char-buf[MAXC];
/*在保留数组空间的同时,将文件中的每一行读取到struct中*/
而(n
虽然您可以在读取文件时简单地获取乘客数量,但您可能会在程序中的某一点读取数据,然后根据需要使用这些信息。因此,在将所有文件数据读取到结构数组中后,返回乘客数量的简单函数可以如下所示:

size_t getpassengercount (struct arrival_struct *s, size_t n)
{
    size_t count = 0, i;
    for (i = 0; i < n; i++)
        count += s[i].count;

    return count;
}
size\u t getpassengercount(结构到达,大小)
{
大小\u t计数=0,i;
对于(i=0;i
将其全部放在一个简短的示例中读取数据文件,您可以执行以下操作:

#include <stdio.h>

#define MAXS 10     /* if you need a constant, #define one (or more) */
#define MAXC 1024

struct arrival_struct {
    int time;       // time of arrival
    int count;      // number of passengers/seats arriving
};

size_t getpassengercount (struct arrival_struct *s, size_t n)
{
    size_t count = 0, i;
    for (i = 0; i < n; i++)
        count += s[i].count;

    return count;
}

int main(void) {

    struct arrival_struct arrivals[MAXS] = {{ .time = 0 }};
    size_t n = 0;
    char buf[MAXC];

    /* while array space remains, read each line from file into struct */
    while (n < MAXS && fgets (buf, sizeof buf, stdin))
        if (sscanf (buf, "%d %d", &arrivals[n].time, &arrivals[n].count) == 2)
            n++;

    printf ("total passengers: %zu\n", getpassengercount (arrivals, n));
}
#包括
#定义MAXS 10/*如果需要常数,请定义一个(或多个)*/
#定义maxc1024
到达结构{
int time;//到达时间
int count;//到达的乘客/座位数
};
大小\u t getpassengercount(结构到达\u结构*s,大小\u t n)
{
大小\u t计数=0,i;
对于(i=0;i
示例使用/输出

$ ./bin/passengercnt <dat/passengers.txt
total passengers: 18

$./bin/passengercnt我不明白这个问题。@Joshua我的问题是如何将标准输入读入一个结构中,然后我可以对它执行一些操作,比如求和。我知道它不太清楚。对不起!您介意在上面的代码中添加一些注释来解释一下吗?:)@米克尔:那应该会有帮助。一旦你在这个while循环之外,你将如何访问和打印结构数组?使用for循环和类似于
printf的东西(“到达时间:%d\t竞争计数:%d”,到达[j]。时间,到达[j]。计数)
?完全一样。只要索引中有一个有效的
到达结构
对象,它就应该可以工作。我似乎一直遇到一个分段错误。你能检查我上面的编辑并可能为我指出正确的方向吗?我假设是因为我在结构数组的某个地方越界了。
scanf
需要指针。在结构成员前面加上
&
前缀,将地址传递给
scanf
&arrivals[i]。计数
和时间。请注意,while循环条件使用的数字未使用,这将导致奇怪的副作用。
 #define MAXS 10     /* if you need a constant, #define one (or more) */
 ...
    struct arrival_struct arrivals[MAXS] = {{ .time = 0 }};
#define MAXC 1024
...
    size_t n = 0;
    char buf[MAXC];

    /* while array space remains, read each line from file into struct */
    while (n < MAXS && fgets (buf, sizeof buf, stdin))
        if (sscanf (buf, "%d %d", &arrivals[n].time, &arrivals[n].count) == 2)
            n++;
size_t getpassengercount (struct arrival_struct *s, size_t n)
{
    size_t count = 0, i;
    for (i = 0; i < n; i++)
        count += s[i].count;

    return count;
}
#include <stdio.h>

#define MAXS 10     /* if you need a constant, #define one (or more) */
#define MAXC 1024

struct arrival_struct {
    int time;       // time of arrival
    int count;      // number of passengers/seats arriving
};

size_t getpassengercount (struct arrival_struct *s, size_t n)
{
    size_t count = 0, i;
    for (i = 0; i < n; i++)
        count += s[i].count;

    return count;
}

int main(void) {

    struct arrival_struct arrivals[MAXS] = {{ .time = 0 }};
    size_t n = 0;
    char buf[MAXC];

    /* while array space remains, read each line from file into struct */
    while (n < MAXS && fgets (buf, sizeof buf, stdin))
        if (sscanf (buf, "%d %d", &arrivals[n].time, &arrivals[n].count) == 2)
            n++;

    printf ("total passengers: %zu\n", getpassengercount (arrivals, n));
}
$ ./bin/passengercnt <dat/passengers.txt
total passengers: 18