Я работаю над проектом колледжа, и мы должны написать базовую программу CRUD на C. В случае 1 моего переключателя «cpfinput» передается моей функции inserir_servidor, а «nominput» (имя) — нет. Я попытался отладить его, и nominput действительно содержит пользовательский ввод, но когда я печатаю свой массив «nomes» после вызова функции, он пуст.
Пожалуйста, простите меня, если это плохо написанный пост, я новичок в SO.
Как воспроизвести:
1 - Введите 1 и нажмите Enter.
2 - Введите что-нибудь.
3 - Введите что-нибудь.
4 - Введите 5, он должен отображать «0, пробел и все, что вы вставили на шаге 3.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAM 100
char codigos[TAM][9];
char nomes[TAM][255];
char cpfs[TAM][11];
int ocupados[TAM];
int inserir_servidor(char[], char[]);
int alterar_servidor(char[], char[], char[]);
int excluir_servidor(char[]);
int mostrar_servidor(char[]);
int mostrar_servidores();
void inic_ocupados();
int main()
{
char codinput[9], nominput[255], cpfinput[11];
int input = -1;
inic_ocupados();
do
{
printf("1. Inserir um servidor.\n");
printf("2. Alterar um servidor.\n");
printf("3. Excluir um servidor.\n");
printf("4. Mostrar um servidor.\n");
printf("5. Mostrar todos os servidores.\n");
printf("0. Sair do programa.\n");
printf("Escolha: ");
scanf("%d", &input);
switch(input)
{
case 0:
printf("Encerrando...");
return 0;
case 1: //inserir
printf("Insira o nome do servidor: ");
scanf(" %s", nominput);
printf("Insira o cpf do servidor: ");
scanf(" %s", cpfinput);
inserir_servidor(nominput, cpfinput);
break;
case 2: //alterar
printf("Insira o codigo do servidor: ");
scanf(" %s", codinput);
printf("Insira um novo nome: ");
scanf(" %s", nominput);
printf("Insira um novo cpf: ");
scanf(" %s", cpfinput);
alterar_servidor(codinput, nominput, cpfinput);
break;
case 3: //excluir
printf("Digite o codigo do servidor a ser excluido: ");
scanf(" %s", codinput);
excluir_servidor(codinput);
break;
case 4: //listar um
printf("Digite o codigo do servidor a ser mostrado: ");
scanf(" %s", codinput);
mostrar_servidor(codinput);
break;
case 5: //listar todos
mostrar_servidores();
break;
default:
printf("Escolha invalida.\n");
break;
}
} while(input);
return 0;
}
int inserir_servidor(char nominput[], char cpfinput[])
{
for(int i = 0; i < TAM; i++)
{
if (!ocupados[i])
{
itoa(i, codigos[i], 10);
strcpy(nomes[i], nominput);
strcpy(cpfs[i], cpfinput);
ocupados[i] = 1;
return 1;
}
}
return 0;
}
int alterar_servidor(char codinput[], char nominput[], char cpfinput[])
{
for(int i = 0; i < TAM; i++)
{
if (!strcmp(codigos[i], codinput))
{
strcpy(nomes[i], nominput);
strcpy(cpfs[i], cpfinput);
return 1;
}
}
return 0;
}
int excluir_servidor(char codinput[])
{
for(int i = 0; i < TAM; i++)
{
if (!strcmp(codigos[i], codinput))
{
ocupados[i] = 0;
return 1;
}
}
return 0;
}
int mostrar_servidor(char codinput[])
{
for(int i = 0; i < TAM; i++)
{
if (!ocupados[i])
{
if (!strcmp(codigos[i], codinput))
{
printf("Codigo \t Nome \t CPF\n");
printf("%s \t %s \t %s\n", codigos[i], nomes[i], cpfs[i]);
return 1;
}
}
}
return 0;
}
int mostrar_servidores()
{
for(int i = 0; i < TAM; i++)
{
if (ocupados[i])
{
printf("Codigo \t Nome \t CPF\n");
printf("%s \t %s \t %s\n", codigos[i], nomes[i], cpfs[i]);
}
}
return 0;
}
void inic_ocupados()
{
for(int i = 0; i < TAM; i++)
{
ocupados[i] = 0;
}
}
jamescodec, Слишком длинный ввод. Замените все scanf()
на fgets()
.
Если только вы не используете эту программу, никогда не доверяйте пользовательскому вводу. scanf("%d", &input);
обязательно доставят вам неприятности.
Mostrar_servidor - сильно сломанная функция, возможно, это ваша проблема
Объясните, пожалуйста, точную последовательность шагов, которые нам нужно выполнить, чтобы воспроизвести вашу проблему. Я могу исправить вариант 4, но это не то, на что вы жалуетесь
Не беспокойтесь о «Введите 1 и нажмите Enter». Показать явный входной поток. Не запускайте программу в интерактивном режиме. например, запустите команду с вводом, поступающим из канала: printf "1\n\n\n5\n" | ./a.out
Valgrind также не находит UB в программе. Вы уверены, что разместили правильный код
Продолжая поиски UB, я запустил его на Windows и Linux как в отладочной, так и в релизной сборке, ничего.
Вопросы по отладке должны содержать минимальный воспроизводимый пример проблемы, включая точные входные данные, необходимые для воспроизведения ошибки. Описание «Введите что-нибудь» недостаточно. Например, поскольку вы не сообщаете нам, вводите ли вы более 10 символов на шаге 3, у нас нет возможности определить, являетесь ли вы переполняющий буфером cpfinput
.
Я не могу найти ошибку, о которой вы сообщаете.
1. Inserir um servidor.
2. Alterar um servidor.
3. Excluir um servidor.
4. Mostrar um servidor.
5. Mostrar todos os servidores.
0. Sair do programa.
Escolha: 1
Insira o nome do servidor: aaaaa
Insira o cpf do servidor: bbbbb
1. Inserir um servidor.
2. Alterar um servidor.
3. Excluir um servidor.
4. Mostrar um servidor.
5. Mostrar todos os servidores.
0. Sair do programa.
Escolha: 5
Codigo Nome CPF
0 aaaaa bbbbb
1. Inserir um servidor.
2. Alterar um servidor.
3. Excluir um servidor.
4. Mostrar um servidor.
5. Mostrar todos os servidores.
0. Sair do programa.
Escolha:
В коде несколько ошибок.
Сначала scanf(" %s",...
ищет ввод с разделителями-пробелами, поэтому, если я введу это
Escolha: 1
Insira o nome do servidor: mr smith <<<<<=========
Insira o cpf do servidor: 1. Inserir um servidor.
2. Alterar um servidor.
3. Excluir um servidor.
4. Mostrar um servidor.
5. Mostrar todos os servidores.
0. Sair do programa.
Escolha:
«Мистер» воспринимается как «ном», а «кузнец» — как «cpf».
Также эта функция
int mostrar_servidor(char codinput[])
{
for (int i = 0; i < TAM; i++)
{
if (!ocupados[i])
{
if (!strcmp(codigos[i], codinput))
{
printf("Codigo \t Nome \t CPF\n");
printf("%s \t %s \t %s\n", codigos[i], nomes[i], cpfs[i]);
return 1;
}
}
}
return 0;
}
Сломано.
Он смотрит только на незанятые ячейки
if (!ocupados[i])
должно быть
if (ocupados[i])
у меня работает, я нажимаю 1, ввожу 2 строки, затем 5 и получаю список с одной записью и обеими строками.