nixp.ru v3.0

19 марта 2024,
вторник,
06:43:45 MSK

AlexRay написал 19 октября 2017 года в 18:09 (6020 просмотров) Ведет себя неопределенно; открыл 1 тему в форуме, оставил 4 комментария на сайте.

Доброго времени суток.
Нужна помощь.
Написал программу с использованием функции fgets(). Как известно, больше определенного количества она символы не выдает.
Так вот, fgets(str, 10, stdin); выдает на экран только 9 символов (10-й \0). Но у меня и дальше в программе присутствует функция fgets. Если я ввожу больше 9 символов, они записываются в буфер и выдаются при вызове функции fgets в следующий раз, хотя должен вводить эти символы с клавиатуры. Как очистить этот буфер. Испробовал разные функции, ничего не помогает. fflush(stdin) не работает. Ничего не работает.
Вот код (он ещё не завершен, но на этом этапе в цикле выдает значения из буфера):

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <time.h>


int main (){
setlocale(LC_ALL, «Russian»);
srand(time_t(0));
char str[10];
int sch;
int count;

while (1) { // с 17 по 44 строку защита от «дурака» для размерности
count = 0;
sch = 0;
printf(«Введите размерность матрицы \n»);
fgets(str, 10, stdin);
for (int i = 0; i < 9; i++) {
if (str == '\0\′) {
sch = 1;
}
}
if (sch == 1) {
//printf(«%s», str);
}
else if (sch == 0) {
//printf(«%s\n», str);
//printf(«I’m sorry \n»);
}

//printf(«%i \n», strlen(str)); Длинна строки с \0

for (int i = 0; i < (strlen(str)-1); i++) {
if (isdigit(str
)) {
count = count + 1;
}
else { printf(«ERROR!!! \n»); return 1; }
}
if (count = (strlen(str)-1)) { break; }
} //Конец проверки для размерности

int n = atoi(str);
printf(«Размерность матрицы = %i \n», n);

printf(«Введите диапазон данных для элемента матрицы \n»);
printf(«Левый край \n»);

while (1) { // с 52 по 86 строку защита от «дурака» для диапазона данных min
count = 0;
sch = 0;
fgets(str, 10, stdin);
for (int i = 0; i < 9; i++) {
if (str == '\0\′) {
sch = 1;
}
}
if (sch == 1) {
//printf(«%s», str);
}
else if (sch == 0) {

//printf(«%s\n», str);
//printf(«I’m sorry \n»);
}

//printf(«%i \n», strlen(str)); Длинна строки с \0
for (int i = 0; i < (strlen(str) — 1); i++) {
if (i == 0) {
if (str
== '-’) {
count = count + 1;
continue;
}
}
if (isdigit(str)) {
count = count + 1;
}
else {
printf(«ERROR!!! Программа завершается \n»); return 1;
}
}
if (count = (strlen(str) — 1)) { break; }
}
//Конец проверки min
int min = atoi(str);
printf(«Левый барьер = %i \n», min);

printf(«Правый край \n»);

while (1) { // с 93 по 127 строку защита от «дурака» для диапазона данных max
count = 0;
sch = 0;
fgets(str, 10, stdin);
for (int i = 0; i < 9; i++) {
if (str
== '\0\′) {
sch = 1;
}
}
if (sch == 1) {
//printf(«%s», str);
}
else if (sch == 0) {
//printf(«%s\n», str);
//printf(«I’m sorry \n»);
}

//printf(«%i \n», strlen(str)); Длинна строки с \0

for (int i = 0; i < (strlen(str) — 1); i++) {
if (i == 0) {
if (str == '-’) {
count = count + 1;
continue;
}
}
if (isdigit(str
)) {
count = count + 1;
}
else {
printf(«ERROR!!! Программа завершается \n»); return 1;
}
}
if (count = (strlen(str) — 1)) { break; }
} //Конец проверки max

int max = atoi(str);
printf(«Правый барьер = %i \n», max);

if ((max — min) <= 0) {
printf(«Ошибка, max > min!!! Программа завершается \n»);
return 1;
}


int *a = new int [n];
for (int i = 0; i<n; i++) {
a = new int[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a
[j] = (rand() % (max — min + 1) + min);
}
}
printf(«Матрица А \n»);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(«%i », a[j]);
}
printf(«\n»);
}
for (int i = 0; i<n; i++) {
delete[] a
;
}
delete[] a;
return 0;
}

fhunter

Люююююди. Если вы ждёте разумного ответа — сделайте так, чтобы вопрос можно было хотя бы читать (кнопочка «code» в редакторе — с значком «<>» на листе).

Ну а теперь поехали:

if (str == '\0\′) {

 — это что должно было значить? может всё-таки вот так?

if (str[i] == '\0') {

Как убрать лишние символы после 10 — например, читать символы до тех пор, пока не наступит конец строки во входном буфере, например так:

int ch;
do {
    ch =  fgetc(stdin);
} while( !((ch == '\n') || (ch == '\r' ) || (ch == EOF)) );

PS. Код с экрана по сути не читаем. Теги [ code ] и astyle/clang-format/любой форматировщик кода в помощь
PPS. Это явно лабораторная работа и для полноценного понимания, почему так делается — хотелось бы видеть полное задание. Потому, что первый же пример с fgets, правильнее решается с использованием scanf.
PPS2. Если это C — тогда malloc() и free(). delete и new — это уже c++.

AlexRay

Извиняюсь за предоставленные трудности, в первый раз на форуме. Учту это. А само задание вот:

Дана квадратная матрица A порядка n. Получить матрицу (А-E)2+C2, где E — единичная матрица порядка n, а элементы
матрицы C вычисляются по формуле C(ij)= (sgn(i-j)) / (i+j+1).

Мне решение само не нужно, его я в целом знаю. Проблема возникла с так называемой «защитой от дурака».
Про fgetc() почитаю, спасибо за вектор в котором стоит думать.

fhunter

Так зачем тогда fgets() для ввода параметров? Есть scanf (http://en.cppreference.com/w/c/io/fscanf )

AlexRay

Мне нужно выполнить защиту. Я решил через строку, проверяя каждый символ. Если находит хоть одну букву, кавычку и т.д. кроме тире(минус) первым символом, то выдает ошибку и закрывает программу. Потом строку из цифр преобразую функцией atoi() в число типа int. Проблема в том, что при вводе строки нужно знать изначальное количество цифр в ней, но я могу ввести как 12, так и 1436. А количество цифр в них разное. Брать с запасом, тогда лишняя память и тоже можно ввести число, цифр в котором больше указанного количества. (Да на этом уровне память не так важна, но всё равно, от нас требуют как можно меньше памяти использовать). Вот я и решил с помощью fgets() хотя бы ограничить количество символов, превышая которое строка просто обрезается. Но остается «хвост» в буфере. Вот у меня и дилемма. (Я только начинаю в этом деле, буквально месяц с небольшим, поэтому и возникают трудности. Я знаю ещё ДАЛЕКО не всё)

fhunter
#include <stdio.h>
int main(void) { int i; int j; i = scanf("%d",&j); if(i<1) { printf("\nEpic fail, conversion failed\n"); }else { printf("\n"); printf("Successfully read %d numbers, Number read:%d\n",i,j); } return 0; }


Поиграйтесь вот с этим кусочком. В коде возврата scanf есть количество успешно считанных переменных.
Этот блок вполне справляется с проверкой на мусор.

AlexRay

Хорошо, большое вам спасибо за помощь.

AlexRay

Извиняюсь опять. Здесь та же песня. Если я ввожу, например «34аываы», то он выдает только 34. Если же я ещё раз потом вставляю scanf, то туда записывается этот хвост. У меня там такая же проверка, где я должен ввести число с клавиатуры, но на деле я ничего не могу ввести, сразу выводится «Epic fail, conversion failed»

Последние комментарии

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.