Wartość przed kursorem

0
int x=27; cout<<"Podaj x: "; cin>>x;

Jak zrobić, żeby program wpisywał mi tą domyślną wartość 27 przed kursorem?

0

Miał być tag c++, ale zniknął jak odświeżyłem stronę (przez wyłączone cookies).
IOW gdy program poprosi o podanie x, to żeby 27 już było wpisane (jako domyślne).… Wiadomo o co mi chodzi? x-P

0
int x=27; cout<<"Podaj x: 27"; cin>>x;
0

Hm. Wstawić domyślną wartość tak, żeby ją można zmieniać (tzn w taki sposób jak Ty to chcesz...) to raczej się nie da - no dobra, dać to może się i da, bo mało czego zrobić nie można, ale czy w czystym standardowym C++? Bez domieszek zależnych od systemu operacyjnego? Ja takiego sposobu nie znam. ;)

Ale...

int costam = 20;
cout << "Podaj x [domyslnie 20]: ";
string line;
getline(cin, line);
// jeśli line składa się z czegoś więce niż tylko ze znaków białych
  // konwertuj line do int, int zapisz dp costam -- stringstream ss(line); ss >> costam
  // przydałoby się w sumie też dać tu obsługę błędów, bo co jeśli wpiszę "sam se wpisz iksa!"? ;)
uzyj costam;
0

@bo facepalm

xD Chodzi mi o to, że (np.) 27 jest najczęściej wybieraną wartością i jakby była już wpisana przed kursorem, to wystarczyłoby tylko ją zatwierdzić Enterem, ale w razie czego można by ją zmienić.

0

Mi wychodzą do głowy dwa wątki i key_eventbd z jednego do drugiego na ekran, ale to już wyższa szkoła jazdy

0

Trzeba napisać własny odpowiednik cin, który będzie na coś takiego pozwalał. Będzie to zależne od systemu operacyjnego, bo inaczej się obsługuje komunikaty konsoli i zdarzenia klawiatury pod Windowsem, inaczej pod Linuksem itd.
Na pewno nie jest prawdą że się „nie da”.

0

Mam pomysł! Przez nikogo nie lubiany getch może zdziałać cuda, bo nie wypisuje tekstu wczytanego, a kursorem nie rusza więc ma się na tym pełną kontrole. To co chcesz osiągnąć. Wystarczy zrobić funkcje, która będzie wczytywała przez getch, ruszała kursorem, zmieniała tekst.... Troche roboty, ale mniej niż z wątkami. Takie coś już napisałem, ale trzeba by było dodać zwracanie wartości itd...

0

Pomysł Macrona wcieliłem w życie po swojemu, chociaż prawdopodobnie ktoś już to gdzieś, kiedyś, zrobił lepiej. Tak, mam chwilowo wolne i czepiam się takich głupot. ;)
Tu nie tyle trzeba napisać swoją wersję cin, co zaimplementować to co system robi (a z czym cin nie ma nic wspólnego przecież) po swojej stronie.

#include <iostream>
#include <string>
#include <sstream>
#include <conio.h>

namespace my {

    template <typename T>
    class special_input {
    private:
        static bool is_printable(const char c) {
            static const std::string all = 
                    "+-1234567890";

            return !(all.find(c, 0) == std::string::npos);
        }
        
        enum Klawisze {
            ENTER = 13,
            LEFT = 75,
            RIGHT = 77,
            BACKSPACE = 8,
            DELETE = 83,
            INSERT = 82
        };
    
        static const unsigned max_line_length;      
        
        static T cast(const std::string& s) {
            std::stringstream ss;
            T tmp;
            ss << s;
            ss >> tmp;
            return tmp;
        }
        
    public:
        static T get(const std::string& message = "",
                    const std::string& default_value = "", 
                    unsigned line_length = max_line_length) {
            std::string msg = default_value;
            if (max_line_length - message.size() < line_length) {
                line_length = max_line_length - message.size();
            }
            unsigned char c;
            const std::string caret_insert = "|";
            const std::string caret_replace = "_";
            std::string caret_symbol = caret_insert;

            unsigned short caret = msg.size();
            std::cout << message << '[' << msg << caret_symbol << std::string(line_length - msg.size(), ' ') << ']';
            bool insert_mode = true;

            while ((c = getch())) {
                if (c == ENTER) {
                    break;
                } else if (c == LEFT) {
                    if (caret > 0) --caret;
                } else if (c == RIGHT) {
                    if (caret < msg.size()) ++caret;
                } else if (c == DELETE) {
                    if (caret < msg.size()) {
                        msg.erase(caret, 1);
                    }
                } else if (c == BACKSPACE) {
                    if (caret > 0) {
                        msg.erase(--caret, 1);
                    }
                } else if (c == INSERT) {
                    insert_mode = !insert_mode;
                    if (insert_mode) {
                        caret_symbol = caret_insert;
                    } else {
                        caret_symbol = caret_replace;
                    }
                } else if (is_printable(c) && msg.size() < line_length) {
                    if (caret == msg.size() || insert_mode) {
                        msg.insert(caret, 1, c);
                        caret++;
                    } else {
                        msg[caret++] = c;
                    }
                }

                std::cout << '\r' << message << '[';
                if (caret > 0) {
                    std::cout << msg.substr(0, caret);
                }
                std::cout << caret_symbol;
                if (caret < msg.size()) {
                    std::cout << msg.substr(caret, msg.size());
                }
                if (msg.size() < line_length) {
                    std::cout << std::string(line_length - msg.size(), ' ');
                }
                std::cout << ']';
            }

            return cast(msg);
        }
    };
    
    template <typename T>
    const unsigned special_input<T>::max_line_length = 76;
    
    template <>
    std::string special_input<std::string>::cast(const std::string& s) {
        return s;
    }
    
    template <>
    bool special_input<std::string>::is_printable(const char c) {
        static const std::string all = 
                "~!@#$%^&*()_+"
                "`1234567890-="
                "[];'\\,./"
                "{}:\"|<>? "
                "qwertyuiopasdfghjklzxcvbnm"
                "QWERTYUIOPASDFGHJKLZXCVBNM"
                "ęóąśłżźćń"
                "ĘÓĄŚŁŻŹĆŃ";

        return !(all.find(c, 0) == std::string::npos);
    }
    
    template <>
    bool special_input<unsigned>::is_printable(const char c) {
        static const std::string all = 
                "1234567890";

        return !(all.find(c, 0) == std::string::npos);
    }
    template <>
    bool special_input<unsigned long>::is_printable(const char c) {
        static const std::string all = 
                "1234567890";

        return !(all.find(c, 0) == std::string::npos);
    }
    template <>
    bool special_input<unsigned short>::is_printable(const char c) {
        static const std::string all = 
                "1234567890";

        return !(all.find(c, 0) == std::string::npos);
    }
    
    template <>
    bool special_input<float>::is_printable(const char c) {
        static const std::string all = 
                "+-.1234567890";

        return !(all.find(c, 0) == std::string::npos);
    }
    template <>
    bool special_input<double>::is_printable(const char c) {
        static const std::string all = 
                "+-.1234567890";

        return !(all.find(c, 0) == std::string::npos);
    }
}

int main() {
    using namespace my;
    using namespace std;
    
    string imie = special_input<string>::get("Podaj imie: ", "Marek", 30);
    std::cout << '\n';
    int lata = special_input<int>::get("Podaj wiek: ", "18", 8);
    
    cout << "\nWitaj " << imie << ", masz " << lata << " lat! :)\n";
    return 0;
}

Zaczynam myśleć, że rozwiązanie z wątkami byłoby lepsze. ;) Ktoś na ochotnika się pobawi?
edit: Lekko zmieniłem kod.

0
bool is_printable(const char c)

dlaczego tak drastycznie ograniczasz dopuszczalne znaki?

1 użytkowników online, w tym zalogowanych: 0, gości: 1