2022년 12월 13일 화요일

C 언어 Trim (불필요한 공백 지우기)

 Trim

불필요한 공백 지우기


#include <stdio.h>

#include <string.h>

#include <ctype.h>


#define MAX_STR_LEN 4000


int main(void) {

    char s[MAX_STR_LEN] = "  AAAA  BBBB CC        DDDD    a ";

    char t[MAX_STR_LEN] = {0, };

    int i=0, len=0, j=0;

    int ltrim = 0;


    len = strlen(s);


    for(i=0 ; i<len ; i++)

    {

        if(ltrim == 0) {

            if(s[i] == ' ') {

                continue;

            }

            else {

                ltrim = 1;

                t[j] = s[i];

                j++;

            }

        } else {

            t[j] = s[i];

            j++;

            if(s[i] == ' ') {

                while(1)

                {

                    i++;

                    if(s[i] == ' ') {

                        continue;

                    } else {

                        t[j] = s[i];

                        j++;

                        break;

                    }

                }

            }

        }


    }

    if(t[j-1] == ' ') {

        t[j-1] = 0;

    }

    printf("=== %s", t);


    return 0;

}

2020년 3월 26일 목요일

QT : QwtExample4

https://github.com/richelbilderbeek/QwtExample4



QT : QwtExample1


https://github.com/richelbilderbeek/QwtExample1


#include <cmath>
#include <QApplication>
#include <QTimer>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_point_data.h>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QwtPlot plot(QwtText("QwtExample1"));
plot.setGeometry(0,0,640,400);
plot.setAxisScale(QwtPlot::xBottom, 0.0,2.0 * M_PI);
plot.setAxisScale(QwtPlot::yLeft,-1.0,1.0);
QwtPlotCurve curve("Sine");
std::vector<double> xs;
std::vector<double> ys;
for (double x = 0; x < 2.0 * M_PI; x+=(M_PI / 100.0))
{
xs.push_back(x);
ys.push_back(std::sin(x) * std::cos(x));
}
QwtPointArrayData * const data = new QwtPointArrayData(&xs[0],&ys[0],xs.size());
curve.setData(data);
curve.attach(&plot);
plot.show();
//In demo mode, close after 1 second
if (argc == 2 && argv[1] == std::string("--demo"))
{
QTimer * const timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), &plot, SLOT(close()));
timer->start(1000);
}
return a.exec();
}

QT : Qt QWT Graph 속성 이해하기


- setTitle() : Qwt Plot를 띄웠을 때, Plot의 이름 설정.
- setAxisTitle() : 왼쪽 영역 이름 설정(Y축)
- setAxisTitle() : 하단 영역 이름 설정(X축)
- enableXMin() : 최소 값을 포함해, Plot의 배경 스타일 결정. 아래 예제 화면에선 DotLine 사용.
- setStyle() : Plot 위에 그려질 요소들의 스타일 결정. 아래 예제 화면에선 Hexagon 스타일에 노란색 확인됨.


QT : Qwt 및 Qt Creator. 빠르고 쉽습니다. part2

https://habr.com/en/post/211867/

Qwt 및 Qt Creator. 빠르고 쉽습니다. 2 부 : 디스플레이 및 제어 요소

  • 튜토리얼


예제는 Qt Creator 3.0.0 (MinGW) 및 Qwt-6.1.0을 사용했습니다.
이 기사를 이해하려면 독자가 다음을 수행하는 것이 좋습니다.


Qwt 는 프로그램에서 데이터를 시각화하는 프로세스를 크게 단순화 할 수있는 그래픽 라이브러리입니다. 단순화는 다음과 같습니다. 좌표 스케일, 그리드, 데이터 곡선 등과 같은 디스플레이 요소를 수동으로 처방 할 필요가 없습니다. 이러한 요소의 매개 변수 만 설정하면됩니다.

(점진적으로 성장하고있는) 기사 시리즈의 1 호에서는 다음과 같이 설명합니다.
• Qwt를 Qt Creator에 연결했습니다.
• 일정을 세웠다.
• 조정 된 좌표축;
• 그래프의 스케일을 변경합니다 (확대 / 축소).
• 그래프 필드 주위를 이동했습니다.
• 마우스 클릭으로 커서 옆에 좌표를 표시했습니다.

2 부에서는 시각화 도구의 기능을 확장 할 것입니다.
• 상태 표시 줄 추가;
• 클릭 좌표를 변수에 저장하고 상태 표시 줄에 표시합니다.
• 제어판에 버튼을 추가하십시오.
• QwtCounter를 제어판에 추가합니다 (숫자 필드, 화살표로 값을 변경할 수 있음, 그림 참조).
• QwtCounter를 사용하여 그래프 x의 오프셋을 설정합니다.
• 버튼을 클릭하면 이전에 설정 한 값 x만큼 그래프가 이동합니다.

참고 : 이 기사에서는 컨트롤을 추가 할 때 GUI가 사용되지 않습니다.



준비 : 기사 1에 제시된 코드를 기능으로 나누기
이전 기사에서 코드는 전적으로 MainWindow 생성자에서 진행되었습니다 이제 코드를 함수로 나누겠습니다. 약간의 변화가 있습니다 : 더 일찍 곡선 점의 좌표를 직접 적어 놓았다면 이제 배열에서 읽습니다 (주석 참조).
중요 사항 : 새 프로젝트를 작성하는 경우 .pro 파일에 행을 추가하는 것을 잊지 마십시오
CONFIG += qwt 
그런 다음 qmake를 실행하십시오.

다음은 mainwindow.h 파일의 내용입니다
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <qwt_plot.h>
#include <qwt_plot_grid.h>

#include <qwt_legend.h>

#include <qwt_plot_curve.h>
#include <qwt_symbol.h>

#include <qwt_plot_magnifier.h>

#include <qwt_plot_panner.h>

#include <qwt_plot_picker.h>
#include <qwt_picker_machine.h>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private:
    Ui::MainWindow *ui;

    QwtPlot *d_plot;
    void setPlot();

    QwtPlotGrid *grid;
    void setPlotGrid();


    QwtPlotCurve *curve;
    QwtSymbol *symbol;

    void setCurveParameters();

    // новый массив точек кривой
 double pointArray[5][2]; 
    QPolygonF points;
    void addPointsToCurveAndShow();

    QwtPlotMagnifier *magnifier;
    void enableMagnifier();


    QwtPlotPanner *d_panner;
    void enableMovingOnPlot();

    QwtPlotPicker *d_picker;
    void enablePicker();


};

#endif // MAINWINDOW_H



다음은 mainwindow.cpp 파일의 필수 내용입니다.
#include "mainwindow.h"
#include "ui_mainwindow.h"



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Создать поле со шкалами для отображения графика
    setPlot();

    // Включить масштабную сетку
    setPlotGrid();

    // Кривая
    setCurveParameters();
    addPointsToCurveAndShow();

    // Включить возможность приближения/удаления графика
    enableMagnifier();

    // Включить возможность перемещения по графику
    enableMovingOnPlot();

    // Включить отображение координат курсора и двух перпендикулярных
    // линий в месте его отображения
    enablePicker();

}

void MainWindow::setPlot()
{
    // (this) - разместить поле на текущем окне
    // #include <qwt_plot.h>
    d_plot = new QwtPlot( this );

    setCentralWidget(d_plot); // привязать поле к границам окна

    d_plot->setTitle( "Qwt demonstration" ); // заголовок
    d_plot->setCanvasBackground( Qt::white ); // цвет фона

    // Параметры осей координат
    d_plot->setAxisTitle(QwtPlot::yLeft, "Y");
    d_plot->setAxisTitle(QwtPlot::xBottom, "X");
    d_plot->insertLegend( new QwtLegend() );
}

void MainWindow::setPlotGrid()
{
    // #include <qwt_plot_grid.h>
    grid = new QwtPlotGrid();
    grid->setMajorPen(QPen( Qt::gray, 2 )); // цвет линий и толщина
    grid->attach( d_plot ); // добавить сетку к полю графика
}


void MainWindow::setCurveParameters()
{
    //#include <qwt_plot_curve.h>
    curve = new QwtPlotCurve();
    curve->setTitle( "Demo Curve" );
    curve->setPen( Qt::blue, 6 ); // цвет и толщина кривой
    curve->setRenderHint
        ( QwtPlotItem::RenderAntialiased, true ); // сглаживание

    // Маркеры кривой
    // #include <qwt_symbol.h>
    symbol = new QwtSymbol( QwtSymbol::Ellipse,
        QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) );
    curve->setSymbol( symbol );
}


void MainWindow::addPointsToCurveAndShow()
{

    // Добавить точки на ранее созданную кривую
    // Значения точек записываются в массив, затем считываются 
    // из этого массива
    for (int i = 0; i < 5; i++) {
        pointArray[i][0] = 1.0 + 0.5*i;
        pointArray[i][1] = 1.0 + 0.5*i;

        points << QPointF( pointArray[i][0], pointArray[i][1]);
    }

    curve->setSamples( points ); // ассоциировать набор точек с кривой

    curve->attach( d_plot ); // отобразить кривую на графике
}


void MainWindow::enableMagnifier()
{
    // #include <qwt_plot_magnifier.h>
    magnifier = new QwtPlotMagnifier(d_plot->canvas());
    // клавиша, активирующая приближение/удаление
    magnifier->setMouseButton(Qt::MidButton);
}

void MainWindow::enableMovingOnPlot()
{
    // #include <qwt_plot_panner.h>
    d_panner = new QwtPlotPanner( d_plot->canvas() );
    // клавиша, активирующая перемещение
    d_panner->setMouseButton( Qt::RightButton );
}

void MainWindow::enablePicker()
{
    // #include <qwt_plot_picker.h>
    // настройка функций
    d_picker =
            new QwtPlotPicker(
                QwtPlot::xBottom, QwtPlot::yLeft, // ассоциация с осями
    QwtPlotPicker::CrossRubberBand, // стиль перпендикулярных линий
    QwtPicker::AlwaysOn, // всегда включен
    d_plot->canvas() ); // ассоциация с полем

    // Цвет перпендикулярных линий
    d_picker->setRubberBandPen( QColor( Qt::red ) );

    // цвет координат положения указателя
    d_picker->setTrackerPen( QColor( Qt::black ) );

    // непосредственное включение вышеописанных функций
    d_picker->setStateMachine( new QwtPickerDragPointMachine() );
}

MainWindow::~MainWindow()
{
    delete ui;
}


상태 표시 줄 추가
mainwindow.h에 함수 프로토 타입을 작성합니다 :
void setStatusBar();


mainwindow.cpp에 코드 추가

void MainWindow::setStatusBar()
{

#ifndef QT_NO_STATUSBAR
    ( void )statusBar();
#endif

}


MainWindow 생성자에서 함수를 호출합니다.
setStatusBar();


클릭 좌표를 변수에 저장하고 상태 표시 줄에 표시
마우스를 클릭하여 실시간으로 좌표를 표시 할 수 있습니다. 실시간으로 좌표가 커서 근처에 표시되므로 (부품 번호 1의 코드를 약간 수정) 첫 번째 옵션을 구현합니다.
클릭은 이벤트입니다. 따라서이 이벤트 (신호)를 수신 할 슬롯을 만듭니다. 에서 mainwindow.h 새로운 민간 부분과 다음 코드를 추가합니다 :

private Q_SLOTS:
    void click_on_canvas( const QPoint &pos );


mainwindow.cpp에서 슬롯 (기능)을 구현합니다.
void MainWindow::click_on_canvas( const QPoint &pos )
{
    // считываем значения координат клика
    double x = d_plot->invTransform(QwtPlot::xBottom, pos.x());
    double y = d_plot->invTransform(QwtPlot::yLeft, pos.y());

    QString info = "x= " + QString::number(x) +
    "; y = " + QString::number(y);

    // отображаем информацию в строке состояния
    statusBar()->showMessage(info);
}


MainWindow 생성자에서 신호 대 슬롯 쌍을 만듭니다.
// коннектить нужно именно к d_picker, но не к d_plot!
    connect( d_picker, SIGNAL( appended( const QPoint & ) ),
        SLOT( click_on_canvas( const QPoint & ) ) );


화면의 아무 곳이나 컴파일하고 클릭합니다 (그래프의 맨 아래 부분이 표시됨) :


이미 이해했듯이 이중 변수로 기록 된 클릭의 좌표를 원하는대로 사용할 수 있습니다.


제어판 만들기
mainwindow.h에 개인 변수 추가
QToolBar *toolBar;

mainwindow.h에 함수 프로토 타입을 작성합니다 :
void setToolBar ();

mainwindow.cpp에 코드 추가
void MainWindow::setToolBar()
{
    toolBar = new QToolBar( this );

    addToolBar( toolBar );
}

MainWindow 생성자에서 함수를 호출합니다.
setToolBar();

결과 : 툴바
(지금까지 비어 있음) 의 상단 부분에 얇은 스트립이 나타납니다 .


제어판에 버튼 추가
mainwindow.h의 시작 부분에 다음을 추가하십시오 :
#include <QToolButton>

개인 변수를 mainwindow.h 및 개인 프로토 타입 함수에 추가하십시오.
QToolButton *toolButton;
void addCorrectionButton();


mainwindow.cpp에 코드 추가
void MainWindow::addCorrectionButton()
{
    toolButton = new QToolButton( toolBar );

    toolButton->setText( "Change x" );
    toolButton->setCheckable( true );

    toolBar->addWidget( toolButton ); // добавить кнопку на панель инструментов
}

MainWindow 생성자에서 함수를 호출합니다.
addCorrectionButton();



제어판 QwtCounter에 추가
mainwindow.h의 시작 부분에 다음을 추가하십시오 :
#include <QHBoxLayout>
#include <qwt_counter.h>


개인 변수를 mainwindow.h 및 개인 프로토 타입 함수에 추가하십시오.
QWidget     *hBox;
QHBoxLayout *layout;
QwtCounter  *cntDamp;
void addQwtCounter();

mainwindow.cpp에 코드 추가
void MainWindow::addQwtCounter()
{
    // настраиваем параметры установщика смещения
    cntDamp = new QwtCounter();
    cntDamp->setRange( -50, 50 );

    // шаг изменения числа при нажатии одинарной стрелки
    // при нажатии двойной стрелки число изменяется на порядок больше
    cntDamp->setSingleStep( 1.0 );
    cntDamp->setValue( 0 ); // начальное значение

    cntDamp->setEnabled(true);

    // Размещение элемента на панели инструментов

    // новый виджет
    hBox = new QWidget();

    // "контейнер", организущий виджеты в горизонтальной последовательности
    // ассоциируется с объектом типа QWidget.
    layout = new QHBoxLayout( hBox );

    // помещаем в контейнер установщик смещения
    layout->addWidget(cntDamp);

    // без этой строчки установщик смещения будет растянут на всю панель
    layout->addWidget( new QWidget(hBox) , 10 ); // spacer

    // помещаем виджет на уже имеющуюся панель инструментов
    ( void )toolBar->addWidget( hBox );
}


MainWindow 생성자에서 함수를 호출합니다.
addQwtCounter();

결과 :


QwtCounter를 사용하여 그래프 오프셋 x를 설정하십시오.
mainwindow.h의 개인 Q_SLOTS 섹션에서 다른 슬롯을 추가하십시오.
void setPlotCorrection( double coeff );


mainwindow.h에서 개인 변수를 추가하십시오 :
double changeXValue;


mainwindow.cpp에서 슬롯 (기능)을 구현합니다.
void MainWindow::setPlotCorrection( double coeff )
{
    changeXValue = coeff;
}


MainWindow의 생성자에서 추가 된 변수를 초기화하고 신호 슬롯 쌍을 만듭니다.
changeXValue = 0.0;
connect( cntDamp, SIGNAL( valueChanged( double ) ),
      SLOT( setPlotCorrection( double ) ) );


버튼을 클릭하면 그래프를 이전에 설정된 값 x로 옮깁니다.
mainwindow.h의 개인 Q_SLOTS 섹션에서 다른 슬롯을 추가하십시오.
void changeX();

mainwindow.cpp에 슬롯 (함수)을 구현합니다 :
void MainWindow::changeX()
{
    // очистить контейнер точек
    points.clear();

    for (int i = 0; i < 5; i++) {
        pointArray[i][0] += changeXValue;

        points << QPointF( pointArray[i][0], pointArray[i][1]);
    }

    curve->setSamples( points ); // ассоциировать набор точек с кривой

    d_plot->replot();

}


이 줄을 추가하면 코드에 중복이 나타납니다. 그러나 프로그램에는 데모 문자가 있으므로 리팩토링이 수행되지 않았습니다.

MainWindow 생성자에서 신호 대 슬롯 쌍을 만듭니다.
connect( toolButton, SIGNAL(toggled(bool)),
SLOT( changeX() ) );


참고 : 버튼에는 두 가지 위치 (누르거나 누르지 않음)가 있지만이 상태는 프로그램에서 모니터링되지 않습니다.


결과 및 결론
프로그램을 실행하십시오. 숫자로 화살표를 설정하고 버튼을 누릅니다. 그래프는 지정된 양만큼 필드에서 성공적으로 이동합니다.

결론 :
이 기사에서는 컨트롤을 수동으로 추가하고이를 사용하여 그래프를 수정하는 방법을 간단한 예제와 함께 보여줍니다.
컨트롤을 수동으로 추가하는 것은 추가 수동 코딩이 필요한 프로세스입니다. GUI를 사용하고 싶습니다. 이것이 나의 다음 기사에서 다룰 내용입니다.


관심을 가져 주셔서 감사합니다!

추신 : 기사의 디자인에 대한 의견을 남겨주세요. 읽는 것이 편리 했습니까? 아마도 자료의 표현을 바꿀 수 있을까요? 어떻게 요?

링크 :

이 예제의 출처로 보관 : yadi.sk/d/TcMglWvAHWvxT

공식 자원 Qwt : qwt.sourceforge.net Qwt 관련

다양한 문제에 대한 솔루션 모음 :www.qtcentre.org/archive/index.php/f-23.html

부품 번호. Qwt에 대한 기사 1주기 : habrahabr.ru/post/211204

라이브러리 옵션, Qwt의 대안 (감사, GooRoo !)
Www.qcustomplot.com