Пропуск первого поля структуры при заполнении очереди - C (СИ)
Формулировка задачи:
Нужна помощь...После создания первого узла,при добавлении узла ,внесение нового элемента начинается только со второго поля...Почему пропускает первое поле(первую строку) я не понимаю.Так же после очистки очереди,добавление первого узла начинается со второго поля структуры...Не понимаю в чём дело,помогите пожалуйста!
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
typedef struct node
{
char schet1[20]; //расчетный счет плательщика
char schet2[20]; //расчетный счет получателя
int summa; //перечисляемая сумма
struct node *next; //указатель на следующий узел
}Node;
void first();
void add();
void del();
void display();
void length();
void clean();
int enter();
Node *head=NULL,*tail=NULL; //указатель на начало,конец =NULL
char sch1[20]; //расчетный счет плательщика
char sch2[20]; //расчетный счет получателя
int sum; //перечисляемая сумма
void main()
{
_getch();
enter();
}
int enter()
{
system("cls");
char choice;
puts("1. Начальное формирование очереди (создание самого первого узла)");
puts("2. Добавление нового узла в конец очереди");
puts("3. Удаление первого узла из очереди");
puts("4. Вывод данных из всех узлов очереди на экран");
puts("5. Определение длины очереди");
puts("6. Очистка очереди (удаление всех узлов)");
puts("7. Завершение работы программы");
while(1) {
choice=getch();
switch (choice) {
case '1':
first();
break;
case '2':
add(); //Добавление элемента
break;
case '3':
del(); // удаление элемента
break;
case '4':
display(); // отображение элементов очереди
break;
case '5':
length(); // определение длины очереди
break;
case '6':
clean(); // очистка всей очереди
break;
case '7':
puts(">>Завершение работы<<");
return 0;
default:
system("cls");
puts(">>Выбор не сделан,попробуйте ещё раз!<<");
enter();
}
return 0;
}
}
void first() {
Node *p;
if ((head == NULL) && (tail == NULL))
{
p=(Node*)malloc(sizeof(Node));
puts("Введите номер плательщика: \n");
gets(sch1); //ввод строки
strcpy_s(p->schet1, sch1);
puts("Введите номер получателя: \n");
gets(sch2); //ввод строки
strcpy_s(p->schet2, sch2);
puts("Введите сумму платежа: \n");
scanf("%d",&sum);
p->summa = sum; //ввод значений
p->next = NULL; //указатель на след элемент = NULL
head = tail = p; //указателю конца и начала присваивается значение элемента очереди(узла)
getch();
enter();
}
else
puts(">>Первый элемент уже создан<<");
getch();
enter();
}
void add() {
Node* p;
if ((head == NULL) && (tail == NULL))
{
puts(">>Сначала создайте первый элемент<<");
getch();
enter();
}
else {
p=(Node*)malloc(sizeof(Node));
puts("Введите номер плательщика: \n");
gets(sch1);
strcpy_s(p->schet1, sch1);
puts("Введите номер получателя: \n");
gets(sch2);
strcpy_s(p->schet2, sch2);
puts("Введите сумму платежа: \n");
scanf("%d",&sum);
p->summa = sum;
p->next=NULL;
tail->next=p;
tail=p;
puts(">>элемент добавлен<<");
getch();
enter();
}
}
void del() {
puts(">>Удаление элемента<<");
Node* p=head;
if(head!=NULL) {
head=head->next;
if(head==NULL)
tail=NULL;
free(p);
}
getch();
enter();
}
void display() {
Node* p=head;
if (p==NULL)
printf(">>Очередь пуста<<\n");
else
printf(">>>>>>>>>Очередь :\n");
while (p!=NULL) {
printf("Номер плательщика:%s\nНомер получателя:%s\nСумма платежа:%d\n", p->schet1, p->schet2, p->summa);
puts("___________________");
p=p->next;
}
getch();
enter();
}
void length(){
Node* p = head;
int count = 0;
int c;
while (p!= NULL)
{
count++;
p = p->next;
}
printf("Длина очереди :\n%d\n\n",count);
getch();
enter();
}
void clean() {
puts(">>Очистка очереди<<");
if(head==NULL && tail==NULL) {
puts(">>Очередь пуста<<");
getch();
enter();
}
else
{
node *p;
while(head!=NULL && tail!=NULL)
{
p=head;
head=p->next;
delete p;
}
head=NULL;
tail=NULL;
puts(">>Очередь удалена<<");
}
}
Нашёл способ как исправить,всё оказалось очень легко,вот готовый вариант.Добавил fflush(stdin); после ввода полей.
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
typedef struct node
{
char schet1[20]; //расчетный счет плательщика
char schet2[20]; //расчетный счет получателя
int summa; //перечисляемая сумма
struct node *next; //указатель на следующий узел
}Node;
void first();
void add();
void del();
void display();
void length();
void clean();
int enter();
Node *head=NULL,*tail=NULL; //указатель на начало,конец =NULL
char sch1[20]; //расчетный счет плательщика
char sch2[20]; //расчетный счет получателя
int sum; //перечисляемая сумма
void main()
{
_getch();
enter();
}
int enter()
{
system("cls");
char choice;
puts("1. Начальное формирование очереди (создание самого первого узла)");
puts("2. Добавление нового узла в конец очереди");
puts("3. Удаление первого узла из очереди");
puts("4. Вывод данных из всех узлов очереди на экран");
puts("5. Определение длины очереди");
puts("6. Очистка очереди (удаление всех узлов)");
puts("7. Завершение работы программы");
while(1) {
choice=getch();
switch (choice) {
case '1':
first();
break;
case '2':
add(); //Добавление элемента
break;
case '3':
del(); // удаление элемента
break;
case '4':
display(); // отображение элементов очереди
break;
case '5':
length(); // определение длины очереди
break;
case '6':
clean(); // очистка всей очереди
break;
case '7':
puts(">>Завершение работы<<");
return 0;
default:
system("cls");
puts(">>Выбор не сделан,попробуйте ещё раз!<<");
enter();
}
return 0;
}
}
void first() {
Node *p;
if ((head == NULL) && (tail == NULL))
{
p=(Node*)malloc(sizeof(Node));
puts("Введите номер плательщика: \n");
gets(sch1); //ввод строки
strcpy_s(p->schet1, sch1);
puts("Введите номер получателя: \n");
gets(sch2); //ввод строки
strcpy_s(p->schet2, sch2);
puts("Введите сумму платежа: \n");
scanf("%d",&sum);
p->summa = sum; //ввод значений
fflush(stdin);
p->next = NULL; //указатель на след элемент = NULL
head = tail = p; //указателю конца и начала присваивается значение элемента очереди(узла)
getch();
enter();
}
else
puts(">>Первый элемент уже создан<<");
getch();
enter();
}
void add() {
Node* p;
if ((head == NULL) && (tail == NULL))
{
puts(">>Сначала создайте первый элемент<<");
getch();
enter();
}
else {
p=(Node*)malloc(sizeof(Node));
puts("Введите номер плательщика: \n");
gets(sch1);
strcpy_s(p->schet1, sch1);
puts("Введите номер получателя: \n");
gets(sch2);
strcpy_s(p->schet2, sch2);
puts("Введите сумму платежа: \n");
scanf("%d",&sum);
p->summa = sum;
fflush(stdin);
p->next=NULL;
tail->next=p;
tail=p;
puts(">>элемент добавлен<<");
getch();
enter();
}
}
void del() {
puts(">>Удаление элемента<<");
Node* p=head;
if(head!=NULL) {
head=head->next;
if(head==NULL)
tail=NULL;
free(p);
}
getch();
enter();
}
void display() {
Node* p=head;
if (p==NULL)
printf(">>Очередь пуста<<\n");
else
printf(">>>>>>>>>Очередь :\n");
while (p!=NULL) {
printf("Номер плательщика:%s\nНомер получателя:%s\nСумма платежа:%d\n", p->schet1, p->schet2, p->summa);
puts("___________________");
p=p->next;
}
getch();
enter();
}
void length(){
Node* p = head;
int count = 0;
int c;
while (p!= NULL)
{
count++;
p = p->next;
}
printf("Длина очереди :\n%d\n\n",count);
getch();
enter();
}
void clean() {
puts(">>Очистка очереди<<");
if(head==NULL && tail==NULL) {
puts(">>Очередь пуста<<");
getch();
enter();
}
else
{
node *p;
while(head!=NULL && tail!=NULL)
{
p=head;
head=p->next;
delete p;
}
head=NULL;
tail=NULL;
puts(">>Очередь удалена<<");
}
}
Он тоже неправильно работает....Нужно перед каждым вводом в поле вставить fflush(stdin);
Решение задачи: «Пропуск первого поля структуры при заполнении очереди»
textual
Листинг программы
while( getchar() != '\n' );
Объяснение кода листинга программы
- В начале программы открывается стандартный ввод (stdin).
- Затем в цикле while считывается каждый символ из стандартного ввода до тех пор, пока не встретится символ новой строки '\n'.
- Каждый символ добавляется в конец буфера, пока буфер не заполнится.
- Когда встречается символ новой строки, буфер очищается и процесс начинается заново.
- Код не обрабатывает символы новой строки, поэтому они остаются в буфере и могут быть считанными в следующей итерации цикла.
- Код не обрабатывает символы возврата каретки '\r', которые могут быть в буфере.
- Код не обрабатывает символы перевода строки '\n\r', которые могут быть в буфере.
- Код не обрабатывает символы перевода страницы '\f', которые могут быть в буфере.
- Код не обрабатывает символы удаления '\b', которые могут быть в буфере.
- Код не обрабатывает символы пробела '\s', которые могут быть в буфере.
- Код не обрабатывает символы табуляции '\t', которые могут быть в буфере.
- Код не обрабатывает символы заголовка '\033', которые могут быть в буфере.
- Код не обрабатывает символы перевода регистра '\r', которые могут быть в буфере.
- Код не обрабатывает символы двубайтных символов, которые могут быть в буфере.
- Код не обрабатывает символы многобайтных символов, которые могут быть в буфере.
- Код не обрабатывает символы не ASCII, которые могут быть в буфере.
- Код не обрабатывает символы кодовой страницы ISO-8859-1, которые могут быть в буфере.
- Код не обрабатывает символы кодовой страницы ISO-8859-2, которые могут быть в буфере.
- Код не обрабатывает символы кодовой страницы ISO-8859-3, которые могут быть в буфере.
- Код не обрабатывает символы кодовой страницы ISO-8859-4, которые могут быть в буфере.