C/C++

Помогите убрать лишнюю строчку в выводе С++

Есть процедура построения треугольника. Там я ввожу 6 координат (для упрощения показываю ввод x1). При вызове это процедуры второй раз. На экране выходит до того как я что-то введу:"" Введите координаты первой вершины треугольника: x1= x1
x1 - не число". Я так понимаю fgets(k, 10, stdin); как то на это влияет, но что сделать, чтобы x1 считывал моё число, а не присваивал x1 не пойму.

void postr_treug() {
int bad = 1;
char k[10], * pend;//для x1
while (bad) {
cout « "Введите координаты первой вершины треугольника:" « endl;
cout « "x1=";
fgets(k, 10, stdin);
x1 = strtol(k, &pend, 10);
if (strlen(k) < 2 || *pend != '\n') {
printf("x1 - не число\n");
}
else { bad = 0; }
#include <iostream>
#include <string>
using namespace std;
struct Point {
Point() : x(0), y(0) {}
double x;
double y;
double length(const Point& p)const {
return sqrt(pow(p.x - x, 2) + pow(p.y - y, 2));
}
};
struct Triangle {
Triangle() = default;
Point a;
Point b;
Point c;
double perimeter()const {
return a.length(b) + b.length(c) + c.length(a);
}
double area()const {
auto p = perimeter() / 2;
auto ab = a.length(b);
auto bc = b.length(c);
auto ca = c.length(a);
return sqrt(p * (p - ab) * (p - bc) * (p - ca));
}
bool is_exist()const {
auto p = perimeter() / 2;
auto ab = a.length(b);
auto bc = b.length(c);
auto ca = c.length(a);
if ((p - ab) * (p - bc) * (p - ca) <= 0) return false;
if ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) == 0) return false;
return true;
}
};
double input_double(string name) {
cout << name;
double value;
cin >> value;
return value;
}
Point input_point(string name) {
Point p;
p.x = input_double(name + "x: "s);
p.y = input_double(name + "y: "s);
return p;
}
Triangle input_triangle() {
Triangle t;
t.a = input_point("A"s);
t.b = input_point("B"s);
t.c = input_point("C"s);
return t;
}
int main() {
system("chcp 1251 > nul");
auto triangle = input_triangle();
if (triangle.is_exist()) {
auto perimeter = triangle.perimeter();
auto area = triangle.area();
cout << "Площадь: " << area << '\n'
<< "Периметр: " << perimeter << '\n';
} else {
puts("Треугольник не существует!");
}
system("pause > nul");
}
Олег Епифанов
Олег Епифанов
54 882
Лучший ответ
Сергей Бушаев Прекрасный ответ, немалый труд, но, Николай, Вы опустили контроль пользователя, а у автора такая попытка есть!
Artiko, а мне не понятно, почему Вы смешиваете C++ и Си! Переменная bad Вам не требуется, заголовок цикла — while (true) или while (1), а принудительный выход из цикла — break.
  Похвально, что Вы сначала читаете строку, потом преобразуете в число — это хотя бы работает быстрее, чем просто считывание числа. Но в C++ для этого всё есть! Используйте тип string и читайте строку функцией getline. А для преобразования строки в число используйте функцию из семейства sto<?> (их несколько, например, stol).
  Также Вы можете просто запрашивать число в потоковом вводе (при помощи библиотеки iostream), а корректность ввода контролировать по состоянию потока.
UU
Unknown Unknown...
16 172
Unknown Unknown...   Проверить состояние потока cin можно: сразу после операции ввода — по возвращаемому значению, а ниже ввода — с помощью методов cin.good(), cin.fail(). И не забываем восстановить состояние потока с помощью cin.clear().
Unknown Unknown...   А, кстати, Ariko, отметьте ошибку: Вы объявляете символьный массив из 10 элементов, и в функции fgets второй аргумент равен 10. Но функция fgets в любом случае к строке добавляет символ '\0', для которого требуется дополнительная ячейка того же массива. Одно из двух: либо массив должен быть из 11 элементов, либо в функции fgets второй аргумент равен 9. Именно тогда гарантирована корректная работа функции strlen, поскольку она определяет длину строки по положению нуль-символа.
Unknown Unknown...   И что за условие strlen(k) < 2? Разве координата не может быть выражена одной цифрой?
Unknown Unknown... RE: «Помогите убрать лишнюю строчку в выводе С++»

Ariko, в своём коде Вы употребляете и cout, и printf, то есть смешиваете в одной программе вывод через iostream и через stdio. Однако cout тоже привязан к stdio, но непосредственный вывод с помощью printf обгоняет cout. Как следствие, строка "x1 - не число" попадает в буфер stdio раньше времени.

Простой совет: используйте для вывода на экран что-нибудь одно.
Unknown Unknown...   Пожалуйста, будьте внимательнее!

  Вы забыли объявить переменную x1 (может быть Вы объявили её выше по коду, но мне этого не видно). При этом Вы присваиваете переменной x1 значение выражения. Что из этого получится?
Проверка корректного ввода, если нужно

#include
#include
#include

class Vertex
{
public:
Vertex()
{
mX = 0;
mY = 0;
}

int getX()
{
return mX;
}

int getY()
{
return mY;
}

void setXY(int x, int y)
{
mX = x;
mY = y;
}

private:
int mX;
int mY;
};

Vertex inputCoords(Vertex &v)
{
std::string inputString;

std::cout << "Введите координаты через пробел: ";

getline(std::cin, inputString);

if (!inputString.compare("exit"))
exit(0);

std::string strX;
std::string strY;

bool splitFlag = false;

try
{
for (size_t i = 0; i < inputString.length(); ++i)
{
if (inputString[i] == ' ')
{
splitFlag = true;
continue;
}

if (!splitFlag)
strX.push_back(inputString[i]);
else
{
strY.push_back(inputString[i]);
}
}

v.setXY(std::stoi(strX), std::stoi(strY));
}
catch(std::invalid_argument ex)
{
std::cout << "Некорректный ввод!" << " " << std::endl;
inputCoords(v);
}

return v;
}
Валидация ввода
int main()
{
setlocale(LC_ALL, "rus");

Vertex points[3];

for (int i = 0; i < 3; ++i)
{
points[i] = inputCoords(points[i]);
}

std::cout << points[0].getX() << " " << points[0].getY() << std::endl;
std::cout << points[1].getX() << " " << points[1].getY() << std::endl;
}
Ivan A
Ivan A
1 676