Archiwum kategorii: C++ / C / Cpp

Examples of QString::number

Some examples of a very useful Qt function: QString::number. This function is helpful in converting double/float to string. QString, to be more precise 😉

QString::number has got 3 parameters:

  • double n – number, which will be converted
  • char format = ‚g – format: available formats are f, e, E, g, G. Default is ‚g’:
  • int precision = 6 – precision.

Let me show some examples. On the end of each line is a output from console:


//f - float
QString::number(3.14159265359, 'f', 0); //3
QString::number(3.14159265359, 'f', 1); //3.1
QString::number(3.14159265359, 'f', 2); //3.14
QString::number(3.14159265359, 'f', 15);//3.141592653590000

//e - exponential notation
QString::number(3.14159265359, 'e', 15); //3.141592653590000e+00
QString::number(3.14159265359, 'E', 15); //3.141592653590000E+00

//g/G - "general" - in this case: "f"
QString::number(3.14159265359, 'g', 0); //3
QString::number(3.14159265359, 'g', 1); //3
QString::number(3.14159265359, 'g', 2); //3.1
QString::number(3.14159265359, 'g', 15); //3.14159265359

QString::number(3.14159265359, 'G', 2); //3.1
QString::number(3.14159265359, 'G', 15); //3.14159265359

//g/G - "general" - in this case: "e/E"
QString::number(2.5e+5, 'g', 0); //2e+05
QString::number(2.5e+5, 'g', 1); //2e+05
QString::number(2.5e+5, 'g', 2); //2.5e+05
QString::number(2.5e+5, 'g', 15); //250000

QString::number(2.5e+5, 'G', 2); //2.5E+05
QString::number(2.5e+5, 'G', 15); //250000

//comparision with f and e/E:
QString::number(2.5e+5, 'f', 2); //250000.00

QString::number(2.5e+5, 'e', 15); //2.500000000000000e+05
QString::number(2.5e+5, 'E', 2); //2.50E+05

Parsowanie ciągu znaków do double w C++

Parsowanie ciągu znaków do typu double jest osiągalne dzięki funkcji strtod.

Przykład:

char* pEnd;
double d1;

d1 = strtod ("3.14", &pEnd);
cout << d1 <<endl;//3.14

d1 = strtod ("12,34", &pEnd);
cout << d1 <<endl;//12

d1 = strtod ("-1.55211e-016", &pEnd);
cout << d1 <<endl;//-1.55211e-16

d1 = strtod ("8.67548e-017", &pEnd);
cout << d1 <<endl;//8.67548e-17

d1 = strtod ("8.67548e+1017", &pEnd);
cout << d1 <<endl;//inf

d1 = strtod ("abc", &pEnd);
cout << d1 <<endl;//0

d1 = strtod ("", &pEnd);
cout << d1 <<endl;//0

d1 = strtod (NULL, &pEnd);
cout << d1 <<endl;//exit!

Qt i problemy z atof()

W projekcie, nad którym aktualnie pracuję, natknęłam się na pewien problem, który spowodował nieprawidłowe działanie dużego fragmentu aplikacji napisanej w C, dołączonej do interfejsu implementowanego w Qt (używam wersji 4.8.0, choć nie ma to zbyt wielkiego znaczenia).

Okazało się że część analityczna programu używała  w wielu miejscach funkcji atof() do przekształcania liczb zapisanych w pliku w postaci ddd.ddd (separatorem była zatem kropka).

#include <cstdlib>
double atof( const char * str );

Funkcja nie odczytywała części dziesiętnych z powodu nieprawidłowego traktowania separatora. Ten poważny błąd, uniemożliwiający działanie całego programu wystarczyło naprawić jedną linijką:

setlocale(LC_NUMERIC,"C");

Linijkę tę należy umieścić w pliku main.cpp, tuż po utworzeniu obiektu typu QApplication. Teraz mój plik wygląda następująco:

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    setlocale(LC_NUMERIC,"C");

    MainWindow w;
    w.show();

    return a.exec();
}

I – wszystko działa 🙂

Wyświetlanie kodu znaków

Jak uzyskać kod znaku? Pisałam o wyświetlaniu kodów znaków przez linuksową aplikację. Można jednak napisać swój program, który jest banalny w swej prostocie – zwłaszcza w C. I działa niezależnie od systemu:)

W tym celu wystarczy wyświetlić znak (char) jako liczbę (int), np.:

printf("znak entera: %d\n", '\n');
printf("znak spacji: %d\n", ' ');
printf("znak r: %d\n", '\r');
printf("znak a: %d\n", 'a');

Takie rozwiązanie często pojawia się w prostych konsolowych programach, w których nawigacja po aplikacji opiera się o konkretne znaki specjalne, gdzie w pętli while sprawdzamy, czy wpisany znak jest konkretnym klawiszem nawigacyjnym. Jeśli tak, wykonujemy przypisane mu akcje.

Kolorowy tekst w konsoli Linux – C/C++

Czasem, dla zwiększenia czytelności programu, chcielibyśmy pokolorować tekst wyświetlany w konsoli – np. aby błędy krytyczne wypisywać na czerwono, lub po prostu dla uatrakcyjnienia wyglądu programu czy skryptu.

kolorykonsoli
Wcale nie trzeba używać do tego bibliotek graficznych. Z pomocą przychodzą opcje już wbudowane w linuxową konsolę – wystarczy na początku wyświetlanego tekstu wpisać odpowiedni kod koloru – np. jak w poniższym przykładzie programu napisanego w języku C/C++:


#include <stdio.h>
void Reset()
{
  printf("%c[%dm ",0x1B,0);//przywrocenie naturalnych kolorow konsoli
}
#define BG_BLACK 40
#define BRIGHT 1
#define RED 31
#define GREEN 32
#define YELLOW 33
#define BLUE 34
#define PINK 35
#define CYAN 36
#define WHITE 37

int main()
{
  printf("%c[%dm Czerwony\n",0x1B,RED);
  printf("Bez kodu, ale nadal w barwie czerwieni\n");
  printf("%c[%dm Zielony\n",0x1B,GREEN);
  printf("Nadal obowiązuje kolor zielony.\n");
  Reset();
  printf("Po resecie: domyślny kolor wraca. \n");
  getchar();
  return 0;
}

Przekazywanie struktur do funkcji w C

Przekazywanie struktur jako argumentów funkcji w języku C jest zupełnie normalne. Czyli bez wskaźników, gwiazdek i tym podobnych znaczników;) Zupełnie jak w językach wysokiego poziomu jak Java czy C#.

przekazywanie_struktur_do_funkcjo

Można to zrobić na przykład tak, w poniższym kodzie:


typedef struct
{
  char chars[100];
  int counter;
} TXT;

void PrettyFunction(TXT structure)
{
  int i=0;
  for( i = 0; i < structure.counter; i++ )
  {
    printf("%c", structure.chars[i]);
  }
}

Tworzenie dynamicznych tablic dwuwymiarowych w C

Ostatnio było o przesyłaniu tablic do funkcji, a dziś o ich tworzeniu – niezbyt chronologicznie, przekornie:)

tworzenie_tablic_2d_w_c

Tablice dynamiczne – czyli takie, gdzie rozmiar tablicy zależy od zmiennych – nie jest ustalany na sztywno podczas pisania aplikacji, lecz ustawiany dopiero gdy np. użytkownik poda, ile danych chce przechowywać w tablicy. Całość zaprezentuję za pomocą przykładów:

Tworzenie i usuwanie tablicy jednowymiarowej:


int *someDynamicArray;
int ile=3;
someDynamicArray = new int[ile];
delete [] someDynamicArray;

Tworzenie i usuwanie tablicy dwuwymiarowej:


int **dynamicArray2d = new int *[3];
for (int i = 0; i < 3; ++i )
{
  dynamicArray2d[i] = new int [2];
}

for (int i=0; i < 3; i++)
{
  delete [] dynamicArray2d[i];
}
delete [] dynamicArray2d;

Tablice wyższych wymiarów (stosowane np. dla zaimplementowania tablicy trójwymiarowych wektorów) tworzy się analogicznie jak tablice drugiego rzędu.

Zaletą tablic dynamicznych jest także możliwość zaalokowania większej ilości pamięci niż w przypadku tablicy statycznej!