Usando todo o seu conhecimento adquirido na disciplina, faça um programa em Linguagem C para controlar o estoque de uma loja com até 10 produtos. O programa deve:
a) Definir um registro (struct) para armazenar: nome do produto (até 30 caracteres), código (inteiro), quantidade em estoque (inteiro) e preço unitário (float).
b) Utilizar um vetor de registros para representar o estoque de produtos.
c) Implementar funções para:
i) Cadastrar um novo produto no estoque.
ii) Atualizar a quantidade de um produto vendido (baixa no estoque por código).
iii) Consultar e exibir todos os produtos com suas quantidades e preços.
iv) Calcular e informar o valor total em estoque da loja.
v) Buscar produto pelo código.
d) Considere tratar os seguintes erros:
i) Validação de entrada do usuário: garantir que campos como quantidade e preço não recebam valores negativos ou zero;
ii) Verificação de código duplicado: antes de cadastrar um novo produto, conferir se o código já existe no vetor, evitando duplicidades;
iii) Busca por código inexistente: ao atualizar estoque ou buscar produto, exibir mensagem informando que o produto não existe se o código não for localizado;
iv) Controle de limites de vetor: impedir cadastro de produto se o número máximo de produtos já foi atingido; avisar o usuário;
v) Atualização de Estoque: evitar baixa que exceda a quantidade em estoque, mostrar mensagem de erro e não permitir a operação;
vi) Mensagens de erro claras: sempre informar o motivo do erro ao usuário e como proceder corretamente.
a) Definir um registro (struct) para armazenar: nome do produto (até 30 caracteres), código (inteiro), quantidade em estoque (inteiro) e preço unitário (float).
b) Utilizar um vetor de registros para representar o estoque de produtos.
c) Implementar funções para:
i) Cadastrar um novo produto no estoque.
ii) Atualizar a quantidade de um produto vendido (baixa no estoque por código).
iii) Consultar e exibir todos os produtos com suas quantidades e preços.
iv) Calcular e informar o valor total em estoque da loja.
v) Buscar produto pelo código.
d) Considere tratar os seguintes erros:
i) Validação de entrada do usuário: garantir que campos como quantidade e preço não recebam valores negativos ou zero;
ii) Verificação de código duplicado: antes de cadastrar um novo produto, conferir se o código já existe no vetor, evitando duplicidades;
iii) Busca por código inexistente: ao atualizar estoque ou buscar produto, exibir mensagem informando que o produto não existe se o código não for localizado;
iv) Controle de limites de vetor: impedir cadastro de produto se o número máximo de produtos já foi atingido; avisar o usuário;
v) Atualização de Estoque: evitar baixa que exceda a quantidade em estoque, mostrar mensagem de erro e não permitir a operação;
vi) Mensagens de erro claras: sempre informar o motivo do erro ao usuário e como proceder corretamente.
Passo 1
O enunciado pede um programa em Linguagem C para controlar o estoque de uma loja com as seguintes exigências e informações fornecidas:
- Capacidade máxima de produtos:
produtos. - Cada produto deve armazenar: nome (até
caracteres), código (inteiro), quantidade em estoque (inteiro) e preço unitário (float). - Deve-se usar um vetor de registros (array de structs) para representar o estoque.
- Funções a implementar:
- Cadastrar um novo produto no estoque.
- Atualizar a quantidade de um produto vendido (baixa por código).
- Consultar e exibir todos os produtos com quantidades e preços.
- Calcular e informar o valor total em estoque da loja.
- Buscar produto pelo código.
- Tratamento de erros exigidos:
- Validar entradas: quantidade e preço não podem ser negativos nem zero.
- Evitar códigos duplicados no cadastro.
- Ao buscar ou atualizar por código inexistente, informar que o produto não existe.
- Impedir cadastro quando vetor já estiver cheio e avisar o usuário.
- Evitar baixa que exceda a quantidade em estoque; informar erro e não permitir a operação.
- Mensagens de erro claras, explicando o motivo e como proceder.
Não vou resolver nada ainda; a partir do próximo passo eu mostro o projeto e a implementação passo a passo.
Passo 2
Definição do registro (struct) e do vetor. Aqui explico por que cada escolha e como isso é usado no programa.
- Vamos criar uma struct chamada
Productcom os campos:char name[31];— espaço para atécaracteres mais o caractere nulo '\0'. Sempre lembramos de reservar +1 para terminar a string.int code;— código inteiro do produto. Vou exigir que seja positivo.int quantity;— quantidade em estoque (inteiro não negativo).float price;— preço unitário (float, maior que zero).
- Por que
char name[31]? Em C as strings ficam armazenadas como arrays decharterminados por'\0'. Se o enunciado pede atécaracteres, precisamos células para guardar o terminador. - Definimos uma constante
#define MAX_PRODUCTS 10para o limite. Isso facilita trocar o limite depois, se necessário.
Explicação didática rápida: uma
struct é um “pacote” de variáveis relacionadas; aqui cada produto é um pacote com nome, código, quantidade e preço. O vetor de structs é só uma lista desses pacotes.Passo 3
Como representar o estoque na memória e variáveis de controle:
- Vamos declarar:
Product inventory[MAX_PRODUCTS];— o vetor que armazena atéprodutos. int numProducts = 0;— contador de quantos produtos já estão cadastrados atualmente no vetor.
- Por que preciso do
numProducts? Em C arrays têm tamanho fixo, mas nem todas as posições estarão ocupadas.numProductsindica até onde existem dados válidos no vetor.
Conceito importante: para inserir, verificamos
if (numProducts >= MAX_PRODUCTS) — se verdadeiro, o estoque está cheio e devemos impedir novo cadastro. Para percorrer produtos válidos usamos índices de 0 até numProducts - 1.Passo 4
Funções que vamos implementar — assinatura, finalidade e comportamento esperado (contrato):
-
int findProductIndexByCode(Product inv[], int n, int code);- Busca produto pelo código
codeno vetorinvcomnitens. - Retorna índice
>= 0se encontrado, ou-1se não existe. - Por que retornar índice? É eficiente para depois atualizar ou exibir.
- Busca produto pelo código
-
int addProduct(Product inv[], int *n);- Tenta cadastrar novo produto no vetor
inv, atualizando*n. - Valida entradas: código positivo, não duplicado; quantidade maior que
; preço maior que . - Verifica limite do vetor: recusa cadastro se
*n >= MAX_PRODUCTS. - Retorna
0em sucesso, e códigos negativos para erros (ex.:-1para vetor cheio,-2para código duplicado,-3para entrada inválida).
- Tenta cadastrar novo produto no vetor
-
int sellProduct(Product inv[], int n);- Faz baixa de estoque por código.
- Pergunta o código, verifica que existe; pede quantidade vendida (deve ser >
e <= quantidade em estoque). - Se válido, subtrai e retorna
0. Se erro (produto não existe, quantidade inválida, insuficiente) retorna código de erro e imprime mensagem apropriada.
-
void listProducts(const Product inv[], int n);- Exibe todos os produtos com código, nome, quantidade e preço formatado.
- Se
n == 0, informa que o estoque está vazio.
-
float calculateTotalValue(const Product inv[], int n);- Percorre os
nprodutos e somaquantity * price. - Retorna o valor total (float). Explico como calcular sem complicar: é uma simples soma acumulada.
- Percorre os
-
void searchProduct(const Product inv[], int n);- Pergunta código, usa
findProductIndexByCodee exibe o produto se encontrado, ou mensagem clara se não existir.
- Pergunta código, usa
Para cada função vou imprimir mensagens claras de sucesso/erro, conforme exigido pelo enunciado.
Passo 5
Validações de entrada e como implementá-las (com exemplos de fluxo de leitura e tratamento de erros):
- Ler strings com segurança:
- Para o nome usamos
fgets(buffer, sizeof(buffer), stdin);e removemos o'\n'final (se presente). Isso evita overflow e problemas com espaços no nome.
- Para o nome usamos
- Ler números com
scanfe verificar retorno:- Ao usar
scanf("%d", &x), sempre verificamos se o retorno é1(entrada válida). Se não, limpamos buffer e re-pedimos. - Para floats usamos
scanf("%f", &f)e verificamos retorno1.
- Ao usar
- Garantir valores positivos:
- Quantidade: exigir
quantity > 0. Não aceitamos0ou negativo. - Preço: exigir
price > 0.0f. - Código: exigir
code > 0.
- Quantidade: exigir
- Evitar duplicidade de código:
- Antes de aceitar um cadastro, chamamos
findProductIndexByCode. Se retorno>= 0, mostramos: “Código já cadastrado — se quiser, use outro código”.
- Antes de aceitar um cadastro, chamamos
- Impedir cadastro quando vetor cheio:
- Se
numProducts >= MAX_PRODUCTSmostramos: “Limite atingido (máx.) — exclua um produto ou aumente o limite.” (mensagem clara).
- Se
- Evitar baixas maiores que estoque:
- Ao vender, se
sellAmount > product.quantity, mostramos “Erro: quantidade solicitada maior que estoque atual (). Operação cancelada.”
- Ao vender, se
- Mensagens de erro:
- Sempre dizer o que aconteceu e o que fazer: ex.: “Entrada inválida: preço deve ser um número real maior que 0. Tente novamente.”
Dica prática: para limpar o buffer após
scanf com falha ou para descartar o '\n' residual, usamos uma função auxiliar void clearInputBuffer(void) que consome int c; while ((c = getchar()) != '\n' && c != EOF);.Passo 6
Implementação passo a passo das funções principais — explicando cada trecho importante (mas sem colar o programa final aqui):
-
findProductIndexByCode:- Percorre
for (int i = 0; i < n; ++i)e comparainv[i].code == code. - Retorna
iquando encontra; se terminar loop retorna-1. - Conceito: busca linear. Para
itens é eficiente e simples.
- Percorre
-
addProduct(fluxo):- Verifica limite:
if (*n >= MAX_PRODUCTS) return -1; - Lê código em loop até obter um
intválido e> 0. Checa duplicidade:if (findProductIndexByCode(inv, *n, code) != -1) informar erro e pedir outro código.
- Lê nome com
fgets, remove'\n'. - Lê
quantityem loop até obterintválido e> 0. - Lê
priceem loop até obterfloatválido e> 0. - Preenche
inv[*n]e incrementa(*n)++;imprime mensagem de sucesso e retorna0.
- Verifica limite:
-
sellProduct(fluxo):- Lê código; usa
findProductIndexByCode; se-1imprime “produto não existe”. - Se existe, mostra estoque atual
inv[idx].quantity. PedeqtdVendida. - Valida
qtdVendida > 0eqtdVendida <= inv[idx].quantity. Se inválido, imprime motivo. - Se válido, faz
inv[idx].quantity -= qtdVendida;e imprime resumo da operação.
- Lê código; usa
-
listProducts:- Se
n == 0, imprime “estoque vazio”. - Senão, imprime cabeçalho e loop mostrando cada produto com
printf("%d\t%-30s\t%d\tR$ %.2f\n", ...). - Explico formatação:
%dinteiro,%-30sstring alinhada à esquerda com largura, %.2fmostra preço comcasas decimais.
- Se
-
calculateTotalValue:- Inicializa
float total = 0.0f;e para cada produto adicionatotal += inv[i].quantity * inv[i].price;. - Retorna
total. Explico que multiplicamos quantidade (inteiro) por preço (float) e somamos — operação elementar.
- Inicializa
-
searchProduct:- Lê código, usa
findProductIndexByCode. Se encontrado exibe os campos do produto; senão, mensagem clara.
- Lê código, usa
-
Menu e loop principal:
- Repetimos até o usuário escolher sair.
- Opções (ex.:
1Cadastrar,2Vender,3Listar,4Valor total,5Buscar,6Sair). - Toda entrada do menu validada: se escolha inválida, mostrar instrução.
Passo 7
Boas práticas e dicas para usar/compilar o programa:
- Compilação típica:
gcc -std=c99 -Wall -Wextra -o estoque estoque.c - Testes que você deve fazer manualmente:
- Tentar cadastrar produto com código repetido — ver mensagem e impedir duplicata.
- Tentar cadastrar com quantidade
ou negativa — ver mensagem e pedir novo valor. - Tentar vender quantidade maior que estoque — ver mensagem e operação não realizada.
- Preencher até o limite de
produtos e tentar cadastrar mais — ver mensagem que limite foi atingido. - Verificar listagem e cálculo do valor total para conferir somas.
- Mensagens no programa são construídas para explicar o erro e indicar como proceder (por exemplo: “Digite um preço maior que 0.0”).
Agora, no próximo campo eu te entrego o programa completo em C que implementa tudo explicado acima.
Resposta
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_PRODUCTS 10
typedef struct {
char name[31]; /* até 30 caracteres + terminador */
int code;
int quantity;
float price;
} Product;
/* Limpa buffer de entrada até '\n' ou EOF */
void clearInputBuffer(void) {
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
/* Busca linear: retorna índice do produto com código igual a code, ou -1 se não achar */
int findProductIndexByCode(Product inv[], int n, int code) {
for (int i = 0; i < n; ++i) {
if (inv[i].code == code) return i;
}
return -1;
}
/* Lista todos os produtos */
void listProducts(const Product inv[], int n) {
if (n == 0) {
printf("Estoque vazio.\n");
return;
}
printf("Código\tNome \tQuantidade\tPreço (R$)\n");
printf("---------------------------------------------------------------------\n");
for (int i = 0; i < n; ++i) {
printf("%6d\t%-30s\t%9d\tR$ %8.2f\n",
inv[i].code,
inv[i].name,
inv[i].quantity,
inv[i].price);
}
}
/* Calcula valor total em estoque */
float calculateTotalValue(const Product inv[], int n) {
float total = 0.0f;
for (int i = 0; i < n; ++i) {
total += inv[i].quantity * inv[i].price;
}
return total;
}
/* Buscar produto pelo código e exibir */
void searchProduct(const Product inv[], int n) {
int code;
printf("Digite o código do produto a buscar: ");
if (scanf("%d", &code) != 1) {
printf("Entrada inválida. O código deve ser um número inteiro positivo.\n");
clearInputBuffer();
return;
}
clearInputBuffer();
int idx = findProductIndexByCode((Product*)inv, n, code);
if (idx == -1) {
printf("Produto com código %d não encontrado.\n", code);
} else {
printf("Produto encontrado:\n");
printf("Código: %d\n", inv[idx].code);
printf("Nome : %s\n", inv[idx].name);
printf("Qtd : %d\n", inv[idx].quantity);
printf("Preço : R$ %.2f\n", inv[idx].price);
}
}
/* Cadastra um novo produto; retorna 0 em sucesso, negativo em erro */
int addProduct(Product inv[], int *n) {
if (*n >= MAX_PRODUCTS) {
printf("Erro: limite de produtos atingido (máx. %d). Não é possível cadastrar.\n", MAX_PRODUCTS);
return -1;
}
int code;
while (1) {
printf("Digite o código do produto (inteiro positivo): ");
if (scanf("%d", &code) != 1) {
printf("Entrada inválida. Digite um número inteiro positivo para o código.\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
if (code <= 0) {
printf("Código deve ser maior que 0. Tente novamente.\n");
continue;
}
if (findProductIndexByCode(inv, *n, code) != -1) {
printf("Código já cadastrado. Use outro código.\n");
continue;
}
break;
}
char nameBuf[256];
while (1) {
printf("Digite o nome do produto (até 30 caracteres): ");
if (fgets(nameBuf, sizeof(nameBuf), stdin) == NULL) {
printf("Erro ao ler o nome. Tente novamente.\n");
clearInputBuffer();
continue;
}
/* Remove newline se presente */
size_t len = strlen(nameBuf);
if (len > 0 && nameBuf[len - 1] == '\n') nameBuf[len - 1] = '\0';
if (strlen(nameBuf) == 0) {
printf("Nome não pode ser vazio. Tente novamente.\n");
continue;
}
if (strlen(nameBuf) > 30) {
printf("Nome muito longo (máx. 30 caracteres). Tente novamente.\n");
continue;
}
break;
}
int quantity;
while (1) {
printf("Digite a quantidade inicial em estoque (inteiro > 0): ");
if (scanf("%d", &quantity) != 1) {
printf("Entrada inválida. A quantidade deve ser um número inteiro maior que 0.\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
if (quantity <= 0) {
printf("Quantidade deve ser maior que 0. Tente novamente.\n");
continue;
}
break;
}
float price;
while (1) {
printf("Digite o preço unitário (maior que 0, ex: 19.90): ");
if (scanf("%f", &price) != 1) {
printf("Entrada inválida. O preço deve ser um número (use ponto para decimal).\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
if (price <= 0.0f) {
printf("Preço deve ser maior que 0. Tente novamente.\n");
continue;
}
break;
}
/* Preenche produto */
inv[*n].code = code;
strncpy(inv[*n].name, nameBuf, 30);
inv[*n].name[30] = '\0'; /* garantia */
inv[*n].quantity = quantity;
inv[*n].price = price;
(*n)++;
printf("Produto cadastrado com sucesso!\n");
return 0;
}
/* Faz baixa no estoque por código (venda). Retorna 0 em sucesso, negativo em erro */
int sellProduct(Product inv[], int n) {
if (n == 0) {
printf("Estoque vazio. Não há produtos para vender.\n");
return -1;
}
int code;
printf("Digite o código do produto a vender: ");
if (scanf("%d", &code) != 1) {
printf("Entrada inválida. Código deve ser inteiro.\n");
clearInputBuffer();
return -2;
}
clearInputBuffer();
int idx = findProductIndexByCode(inv, n, code);
if (idx == -1) {
printf("Produto com código %d não encontrado.\n", code);
return -3;
}
printf("Produto: %s | Estoque atual: %d | Preço unitário: R$ %.2f\n",
inv[idx].name, inv[idx].quantity, inv[idx].price);
int qtd;
while (1) {
printf("Digite a quantidade a vender (inteiro > 0): ");
if (scanf("%d", &qtd) != 1) {
printf("Entrada inválida. A quantidade deve ser um número inteiro maior que 0.\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
if (qtd <= 0) {
printf("Quantidade deve ser maior que 0. Tente novamente.\n");
continue;
}
if (qtd > inv[idx].quantity) {
printf("Erro: quantidade solicitada (%d) maior que estoque atual (%d). Operação cancelada.\n",
qtd, inv[idx].quantity);
return -4;
}
break;
}
inv[idx].quantity -= qtd;
printf("Venda registrada: %d unidade(s) de '%s' vendida(s). Estoque agora: %d\n",
qtd, inv[idx].name, inv[idx].quantity);
return 0;
}
/* Menu principal */
int main(void) {
Product inventory[MAX_PRODUCTS];
int numProducts = 0;
int option;
printf("=== Sistema de Controle de Estoque (até %d produtos) ===\n", MAX_PRODUCTS);
while (1) {
printf("\nEscolha uma opção:\n");
printf("1 - Cadastrar novo produto\n");
printf("2 - Registrar venda (baixa no estoque por código)\n");
printf("3 - Listar produtos\n");
printf("4 - Calcular valor total em estoque\n");
printf("5 - Buscar produto por código\n");
printf("6 - Sair\n");
printf("Opção: ");
if (scanf("%d", &option) != 1) {
printf("Entrada inválida. Digite o número da opção.\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
switch (option) {
case 1:
addProduct(inventory, &numProducts);
break;
case 2:
sellProduct(inventory, numProducts);
break;
case 3:
listProducts(inventory, numProducts);
break;
case 4: {
float total = calculateTotalValue(inventory, numProducts);
printf("Valor total em estoque: R$ %.2f\n", total);
break;
}
case 5:
searchProduct(inventory, numProducts);
break;
case 6:
printf("Encerrando programa. Até mais!\n");
return 0;
default:
printf("Opção inválida. Escolha uma das opções entre 1 e 6.\n");
}
}
return 0;
}