- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试找出如何在结构数组中存储来自用户的信息,但是到目前为止……不起作用。
我创建了该结构,然后在主体内部创建了指向该结构的指针,然后动态分配了该结构。但是我真的不知道如何从用户那里获取信息。我知道,但是没有按预期工作。如果我只使用一个结构体数组,它将是这样的……
&p [i] .id //正常
我尝试使用此方法,但不起作用,idk为什么...代码尚未完成...
//
// 7.c
// IFTM Exercises
//
// Created by Lelre Ferreira on 8/29/19.
// Copyright © 2019 Lelre Ferreira. All rights reserved.
//
#define size 5
#include <stdio.h>
#include <stdlib.h>
struct produtos {
int id;
int quant;
float vlrs;
char nm[50];
};
void cadastroProdutos (struct produtos *p, int tamanho);
void maiorValorProdutos (struct produtos *p, int tamanho);
void maiorEstoqueProdutos (struct produtos *p, int tamanho);
int main (int argc, const char * argv[]){
struct produtos *p;
int tamanho = 0;
printf("Insira quantidade de produtos/itens a serem cadastrados: ");
scanf("%d", &tamanho);
p = (struct produtos *) malloc(tamanho * sizeof(struct produtos));
cadastroProdutos(p, tamanho);
maiorValorProdutos(p, tamanho);
maiorEstoqueProdutos(p, tamanho);
return 0;
}
void cadastroProdutos(struct produtos *p, int tamanho){
int i = 0;
for (i = 0; i < tamanho; i++) {
printf("Insira o ID: ");
scanf("%d", &p[i] -> id);
printf("Insira o nome: ");
scanf("%s", p[i] -> nm);
printf("Insira o valor: ");
scanf("%f", &p[i] -> vlrs);
printf("Insira a quantidade: ");
scanf("%d", &p[i] -> quant);
}
}
void maiorValorProdutos(struct produtos *p, int tamanho){
}
void maiorEstoqueProdutos(struct produtos *p, int tamanho){
}
最佳答案
您错过了理解,将[..]
运算符应用于指针p
(例如p[0]
)充当了取消引用的作用,从而使类型struct produtos
和'.'
运算符正确(而不是@MilesBudnek's中提到的struct produtos*
>回答。
除了您的'.'
或'->'
运算符问题之外,您似乎还缺少动态分配的要点。虽然可以从#define size 5
分配的结构开始,但动态分配内存的目的是能够通过按需重新分配额外的内存来处理所有输入(或直到用完为止)来无缝处理第6个结构有效内存)。
当前编写函数cadastroProdutos
的方式并不能真正实现干净的动态分配(除了它返回void
并且其中没有任何输入有效的事实)。与其在函数中循环size
次,不如只是希望每次调用cadastroProdutos
时都获得1个结构的数据。这样,您可以根据需要多次调用它,直到输入所有数据为止。不需要在函数内循环,并且scanf
的使用非常脆弱,因为由于匹配失败或只是偶然输入了错误字符而无法处理stdin
中遗留的字符,例如('a'
输入id
,或名称长于49
个字符,等等。)
要解决大多数问题,请不要对用户输入使用scanf
,而是将所有用户输入读入大小合适的临时缓冲区(例如1024
字符左右),然后从使用sscanf
缓冲。这具有双重好处,即可以分别验证读取和解析。并且通过使用合理大小的缓冲区,您每次都消耗一整行输入,从而消除了多余的字符问题(例如,踩在键盘上的猫)。
接受输入的cadastroProdutos
没有提供有意义的返回值来指示输入成功/失败,如果任何一个输入失败,则函数容易受到未定义行为的影响。因此,请通过检查所使用功能的返回来验证每个用户的输入。在任何输入失败中,返回0
表示失败,成功时返回非零,则可以在调用函数中处理所有输入失败。
(注意:计数类型应使用size_t
而不是int
)
将这些更改汇总到您的cadastroProdutos
中,您可以执行以下操作:
size_t cadastroProdutos (produtos *p, size_t *tamanho)
{
produtos tmp; /* temporary struct */
char buf[MAXC]; /* temporary buffer */
/* prompt, read-line, validate parse */
fputs ("\nInsira o ID: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%d", &tmp.id) != 1)
return 0; /* (failure) */
fputs ("Insira o nome: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%49[^\n]", tmp.nm) != 1)
return 0;
fputs ("Insira o valor: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%f", &tmp.vlrs) != 1)
return 0;
fputs ("Insira a quantidade: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%d", &tmp.quant) != 1)
return 0;
p[(*tamanho)++] = tmp; /* assign tmp to p[*tamanho], increment */
return *tamanho; /* return tamanho (success) */
}
tamanho
作为指针传递,因此它的编号可以在函数中更新,并且
0
失败时返回,而更新的
tamanho
成功时返回,从而使您可以有意义地返回类型
size_t
)
size
定义了一个常量,现在只需细化定义所需的常量,这样就不再有像
char nm[50];
这样的幻数了。这样做可以使用更多
#define
,例如
#include <stdio.h>
#include <stdlib.h>
#define PROD 2 /* initial no. of struct to allocate */
#define NMSZ 50 /* max name size */
#define MAXC 1024 /* reasonable no. of chars for temporary buffer */
typedef struct { /* a typedef used for convenience */
int id;
int quant;
float vlrs;
char nm[NMSZ];
} produtos;
main()
中需要做的就是声明一个临时缓冲区来保存该行,
size_t
值,当前分配的结构总数(
allocated
)和填充的数量(
tomanho
),从而导致在每个循环
if (tomanho == allocated)
开始时进行简单检查,您知道在尝试填充更多内容之前,需要
realloc
其他结构。您的
main()
函数本质上可以是:
int main (void) {
size_t allocated = PROD, /* initial number of struct to allocate */
tomanho = 0; /* number of allocated structs used */
produtos *p = malloc (allocated * sizeof *p); /* allocate */
if (!p) { /* validate EVERY allocation */
perror ("malloc-p");
return 1;
}
while (cadastroProdutos (p, &tomanho)) { /* loop validating return */
char buf[MAXC]; /* buffer for input (y/n) */
if (tomanho == allocated) { /* is a realloc needed to add struct? */
/* always realloc with a temporary pointer */
void *tmp = realloc (p, 2 * allocated * sizeof *p);
if (!tmp) { /* validate the reallocation */
perror ("realloc-p");
break; /* realloc failed, original p still good, break */
}
p = tmp; /* assign new block of mem to p */
allocated *= 2; /* update no. of structs allocated */
}
fputs ("\n add another (y/n)? ", stdout); /* add more produtos? */
if (!fgets (buf, MAXC, stdin) || !(*buf == 'y' || *buf == 'Y')) {
putchar ('\n');
break;
}
}
p
中,您所需要做的就是处理数据(下面简单输出),然后再处理
free()
已分配的内存,例如
for (size_t i = 0; i < tomanho; i++) /* loop showing stored data */
printf ("p[%2zu] %4d %-20s %6.2f %4d\n",
i, p[i].id, p[i].nm, p[i].vlrs, p[i].quant);
free (p); /* don't forget to free memory you allocate */
}
#include <stdio.h>
#include <stdlib.h>
#define PROD 2 /* initial no. of struct to allocate */
#define NMSZ 50 /* max name size */
#define MAXC 1024 /* reasonable no. of chars for temporary buffer */
typedef struct { /* a typedef used for convenience */
int id;
int quant;
float vlrs;
char nm[NMSZ];
} produtos;
size_t cadastroProdutos (produtos *p, size_t *tamanho)
{
produtos tmp; /* temporary struct */
char buf[MAXC]; /* temporary buffer */
/* prompt, read-line, validate parse */
fputs ("\nInsira o ID: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%d", &tmp.id) != 1)
return 0; /* (failure) */
fputs ("Insira o nome: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%49[^\n]", tmp.nm) != 1)
return 0;
fputs ("Insira o valor: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%f", &tmp.vlrs) != 1)
return 0;
fputs ("Insira a quantidade: ", stdout);
if (!fgets (buf, MAXC, stdin) || sscanf (buf, "%d", &tmp.quant) != 1)
return 0;
p[(*tamanho)++] = tmp; /* assign tmp to p[*tamanho], increment */
return *tamanho; /* return tamanho (success) */
}
int main (void) {
size_t allocated = PROD, /* initial number of struct to allocate */
tomanho = 0; /* number of allocated structs used */
produtos *p = malloc (allocated * sizeof *p); /* allocate */
if (!p) { /* validate EVERY allocation */
perror ("malloc-p");
return 1;
}
while (cadastroProdutos (p, &tomanho)) { /* loop validating return */
char buf[MAXC]; /* buffer for input (y/n) */
if (tomanho == allocated) { /* is a realloc needed to add struct? */
/* always realloc with a temporary pointer */
void *tmp = realloc (p, 2 * allocated * sizeof *p);
if (!tmp) { /* validate the reallocation */
perror ("realloc-p");
break; /* realloc failed, original p still good, break */
}
p = tmp; /* assign new block of mem to p */
allocated *= 2; /* update no. of structs allocated */
}
fputs ("\n add another (y/n)? ", stdout); /* add more produtos? */
if (!fgets (buf, MAXC, stdin) || !(*buf == 'y' || *buf == 'Y')) {
putchar ('\n');
break;
}
}
for (size_t i = 0; i < tomanho; i++) /* loop showing stored data */
printf ("p[%2zu] %4d %-20s %6.2f %4d\n",
i, p[i].id, p[i].nm, p[i].vlrs, p[i].quant);
free (p); /* don't forget to free memory you allocate */
}
add another (y/n)?
提示符,以确定用户是否要添加更多数据)
$ ./bin/produtos
Insira o ID: 1
Insira o nome: John Brown
Insira o valor: 12.34
Insira a quantidade: 415
add another (y/n)? y
Insira o ID: 2
Insira o nome: Mary Brown
Insira o valor: 23.45
Insira a quantidade: 416
add another (y/n)? y
Insira o ID: 3
Insira o nome: Mickey Mouse
Insira o valor: 34.56
Insira a quantidade: 417
add another (y/n)? y
Insira o ID: 4
Insira o nome: Minnie Mouse
Insira o valor: 45.67
Insira a quantidade: 418
add another (y/n)? y
Insira o ID: 5
Insira o nome: Sam Clemens
Insira o valor: 56.78
Insira a quantidade: 419
add another (y/n)? y
Insira o ID: 6
Insira o nome: Mark Twain
Insira o valor: 67.89
Insira a quantidade: 420
add another (y/n)? n
p[ 0] 1 John Brown 12.34 415
p[ 1] 2 Mary Brown 23.45 416
p[ 2] 3 Mickey Mouse 34.56 417
p[ 3] 4 Minnie Mouse 45.67 418
p[ 4] 5 Sam Clemens 56.78 419
p[ 5] 6 Mark Twain 67.89 420
valgrind
)运行任何使用动态内存的程序,该程序可以判断是否不当使用了您不拥有的内存块指针。
$ valgrind ./bin/produtos < dat/produtos.txt
==12885== Memcheck, a memory error detector
==12885== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==12885== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==12885== Command: ./bin/produtos
==12885==
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
Insira o ID: Insira o nome: Insira o valor: Insira a quantidade:
add another (y/n)?
p[ 0] 1 John Brown 12.34 415
p[ 1] 2 Mary Brown 23.45 416
p[ 2] 3 Mickey Mouse 34.56 417
p[ 3] 4 Minnie Mouse 45.67 418
p[ 4] 5 Sam Clemens 56.78 419
p[ 5] 6 Mark Twain 67.89 420
==12885==
==12885== HEAP SUMMARY:
==12885== in use at exit: 0 bytes in 0 blocks
==12885== total heap usage: 3 allocs, 3 frees, 896 bytes allocated
==12885==
==12885== All heap blocks were freed -- no leaks are possible
==12885==
==12885== For counts of detected and suppressed errors, rerun with: -v
==12885== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
"All heap blocks were freed -- no leaks are possible"
并且没有错误。
关于c - 如何动态分配结构+指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57779644/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!