c++ yazılan rakamların yerine **** göstermek?

Başlatan reflection, 20 Mart 2011 - 17:17:34

« önceki - sonraki »

0 Üyeler ve 2 Ziyaretçi konuyu incelemekte.

reflection

yazdığım bir programın bir bölümünde şifre girilmesi gerekiyor fakat girilen rakamlar ekranda gözüyükor. bu rakamların " * " (yıldız) olarak gözükmesini nasıl sağlarım?

yardımcı olucaklara şimdiden teşekkürler.

sem

#1
Şöyle bir şey yapılabilir;


Karakterler bir dizi içerisine aktarlılır... Alınan karakter yerine de * basılabilir... Mesela


char password[30];
int  i = 0;
......
......
......

for(;password[i] != '\n'; ++i){
password[i] = getch();
fprintf(stdout, "*");
}


Buradaki sorun getch() fonksiyonunun bu tarafta olmaması. Bu gerçek bir sorun mudur =) Değildir, internetten hatta bu bölümde yani C/C++ bölümünde getch() fonksiyonunun Linux uyarlaması mevcuttu.

Şunu eklemekte fayda olabilir; kişi silme tuşuna basınca i yi bir azalttırmak kişiye yanlış yazma hakkı tanımaya olanak sağlar. Tabii i'yi en fazla 0 sıfır olana kadar azaltmaya özen göstermek lazım, bir gösterici hatası ile karşılaşmamak için...

Bu sadece fikir tabii... Denemedim, denemek lazım =)
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

reflection

windows ta bu aşağıdaki kod ile yapılabiliyormuş sanırım ama platform bağımsız bir kod bulamadım. sizin bahsettiğizi gibi deniyeceğim bakalım  olacak mı.
aklıma şöyle  bir şey geldi bir de, şifre açık halde yazılır ama yazıldıktan sonra ekrandaki bütün yazılar silinip program kaldığı yerden devam eder. bu tip * bir şey yapılabiir mi?

#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
int main(){
   string pass ="";
   char ch;
   cout << "Enter pass\n";
   ch = _getch();
   while(ch != 13){//character 13 is enter
      pass.push_back(ch);
      cout << '*';
      ch = _getch();
   }
   if(pass == "Mitsakos"){
      cout << "\nAccess granted :P\n";
   }else{
      cout << "\nAccess aborted...\n";
   }
}

sem

Yapmak istediğiniz sanırım böyle bir şey... Fakat nedense \b karakterini tanımadı... Çok merak ettim ben de nedenini =)


#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

int mygetch(void)
{
struct termios oldt,newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}




int main()
{
char password[30];
printf("Şifreyi girin:");
        int i= 0;

        while(1){
            password[i] = mygetch();
            if(password[i] == '\b'){
                fprintf(stdout, "\r%d", strlen(password) -1);
                 continue;
            }
            if(password[i] == '\n'){
                  password[i] = '\0';
                  break;
            }
            fprintf(stdout, "*");
            ++i;
        }
        fprintf(stdout, "\nGirdiğiniz şifre: %s\n", password);
return 0;
}
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Erdem

Ben epey zamandır C++ ile uğraşmadığım için bunun D versiyonunu göstereyim.  ;) Ama mantık aynı:

import std.stdio : writef, writeln, write;
import std.c.stdio;
import std.c.linux.termios;

/*
* Verilen termios yapısını yalın (raw) hale getiren
* işlev. (Nedense bunun bildirimi yukarıdaki modüllerde
* bulunmuyor; onun için kendimiz bildiriyoruz. (?))
*/
extern(C) void cfmakeraw(termios *termios_p);

void main()
{
    /*
     * tty durumunun eski halini kaydediyoruz ve programdan
     * çıkıldığında eski haline çevrilmesini scope (exit) ile
     * garantiliyoruz.
     */
    termios eskiDurum;
    tcgetattr(1, &eskiDurum);
    scope (exit) tcsetattr(1, TCSADRAIN, &eskiDurum);

    /*
     * Yeni durumunu yalın (raw) moda çevir
     */
    termios  yeniDurum;
    tcgetattr(1, &yeniDurum);
    cfmakeraw(&yeniDurum);

    /*
     * Bu terminalde bu yeni durumu kullan
     */
    tcsetattr(1, TCSADRAIN, &yeniDurum);

    /*
     * Şimdi bu yalın moddayken karakterler okuyacağız
     */

    /*
     * Linux'ta Ctrl-D'nin karşılığı (Windows'da Ctrl-Z)
     */
    immutable akımSonu = '\4';

    char karakter;
    while (karakter != akımSonu) {
        karakter = cast(char)fgetc(stdin);
        write ("*");
    }

    writeln();
}


Bunu başka bir arkadaş yazmış. Ben sadece biraz değiştirdim.
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

reflection

teşekkürler yardımlar için biraz uğraştırcak ama olucak sanırım.

sem

        while(1){
            password[i] = mygetch();
            if(password[i] == '\b'){
                fprintf(stdout, "\r%d", strlen(password) -1);
                 continue;
            }
            if(password[i] == '\n'){
                  password[i] = '\0';
                  break;
            }
            fprintf(stdout, "*");
            ++i;
        }


reflection bu yapı işinizi görmedi mi?
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

reflection

mantığını kavradım sanırım ama getch fonksiyonuna aşina değilim ondan beceremedim yazdığınız kodu çalıştırmayı

sem

http://forum.ubuntu-tr.net/index.php/topic,26062.msg312284.html#msg312284


bu iletimdeki programı alıp program.c adı ile kayıt edin...

gcc program.c -o program

Bu şekilde derleyin. Daha sonra

./program

Buı şekilde çalıştırın... Size şifre soracak... Siz şifre yazarken ekranda * karakteri çıkacak... Sıkıntı ise \b karakteri...

Eğer işinize yarayacak olursa programınıza göre yeni fonksiyon oluşturmamız pek sıkıntı oluşturmaz...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Erdem

@sem0900 program çalışıyor.

Yukarıda örnek olarak verdiğim programı denemek isterseniz:

http://ftp.digitalmars.com/dmd_2.052-0_i386.deb

adresinden D derleyicisini tek tıkla kurabilirsiniz. Sonra yukarıdaki dosyayı d uzantılı örneğin deneme.d olarak kaydettikten sonra konsolda:

$ dmd deneme.d

diye derleyip

$ ./deneme

çalıştırabilirsiniz.

Bir de anladığım kadarıyla hem D olsun hem C++ olsun bunu dilin standart olanakları ile yapamıyoruz. Bunun yerine çalışma zamanı (runtime) kütüphaneler kullanıyoruz.

Bir de konu dışı olacak ama D, C'nin standart kütüphanesini kullanabiliyormuş. O yüzden böyle programlar yazmak mümkün :)

Alıntı Yapimport std.c.stdio;
import std.string;

void main()
{
    string selam = "merhaba";
    int sayı = 42;
    printf("%s %d\n", toStringz(selam), sayı);
}

Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

sem

@Erdem... D programını derleyip çalıştırdım... Yalnız şöyle bir sorun oldu bende; ne zaman bittiğini anlamadım şifre almanın... Çünkü enter tuşuna bastığım zaman yine * karakteri koyuyor. ctrl + c ya da   ctrl + z kombinasyonları dahil * karakteri koyuluyor... Yani hangi tuşa basarsam basayım * çıkartıyor ama nasıl sonlandıracağımı bulamadım...

Derken kodları inceledim... "\4" ü gördüm =) Tamamdır sorun kalmadı =) sonlandırmayı da buldum... Programın enter tuşu ile sonlanması sanırım daha makul...

D ile ilgili bir bilgim yok fakat dediğiniz gibi C++ derleyicileri C kodlarını da derleyebiliyor... Yani aynı kütüphaneler dahil edilebiliyor... Zaten C++ daha iyi bir C için çıkartılmış diye okumuştum =) O nedenle C ile ilgili bütün fonksiyonlar C++ ile de kullanılabiliyor sanırım... Tabii bazı farklılıklara dikkat etmek gerekiyor...

void tür dönüşümü otomatik olarak yapılmıyor örneğin adreslerde... C'de bu duruma izin var... Bu gibi farklılıklara dikkat edilerek sanırım hepsi kullanılabiliyor...


Dediğinizde dehaklısınız.... Standart fonksiyonlar ile bu durumu sağlayamıyoruz. Çünkü standart olarak stdin tamponuna yazılan karakteri ekrana yazılmadan okuyan bir fonksiyon yok.  Sistem fonksiyonlarından yararlanmamız gerektiği için standart şekilde sağlayamıyoruz durumu...


Sanırım olay bu =)
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Erdem

#11
Alıntı yapılan: sem0900 - 23 Mart 2011 - 01:38:44
@Erdem... D programını derleyip çalıştırdım... Yalnız şöyle bir sorun oldu bende; ne zaman bittiğini anlamadım şifre almanın... Çünkü enter tuşuna bastığım zaman yine * karakteri koyuyor. ctrl + c ya da   ctrl + z kombinasyonları dahil * karakteri koyuluyor... Yani hangi tuşa basarsam basayım * çıkartıyor ama nasıl sonlandıracağımı bulamadım...

Derken kodları inceledim... "\4" ü gördüm =) Tamamdır sorun kalmadı =) sonlandırmayı da buldum... Programın enter tuşu ile sonlanması sanırım daha makul...

Linux'ta doğal olarak Ctrl-D ile programları sonlandırdığımızdan olabilir mi :)

Bir de dikkat ederseniz sadece örnek vermek için yazılan bir program aslında çıkışa karakterlerin heksadesimal karşılıklarını yazıyordu ben biraz değiştirdim. Ama örneğin dikkat ederseniz karakter kodu 2 bayt yer kaplayan karakterler için 2 tane  ** basıyor. Ben sadece mantık anlaşılsın açısından örnek vermeye çalıştım. Bu tür sorulara karşı tam çözüm vermekten ziyade mantığını anlatmayı daha doğru buluyorum.

Alıntı yapılan: sem0900 - 23 Mart 2011 - 01:38:44
D ile ilgili bir bilgim yok fakat dediğiniz gibi C++ derleyicileri C kodlarını da derleyebiliyor... Yani aynı kütüphaneler dahil edilebiliyor... Zaten C++ daha iyi bir C için çıkartılmış diye okumuştum =) O nedenle C ile ilgili bütün fonksiyonlar C++ ile de kullanılabiliyor sanırım... Tabii bazı farklılıklara dikkat etmek gerekiyor...

C++'nin daha iyi bir C olduğu doğru.  Aslında bu kısmı tam anlamadım ama C fonksiyonlarını koda extern "C" ekleyerek C++ içinden çağırmak mümkün.  C++ öğrenmeye başlayınca C ile ilgili bildiğiniz çoğu şeyi unutmanız gerekecek. C++ gerçekten karmaşık ve uzmanlaşması çok uzun zaman alan  bir dil  ???

D'de bir sistem programlama dili şimdilik kodlama şekli gayet güzel, UTF8 desteği var, ama umarım ilerde o da C++ gibi karmaşık bir dil haline gelmez   :D

Alıntı yapılan: sem0900 - 23 Mart 2011 - 01:38:44
void tür dönüşümü otomatik olarak yapılmıyor örneğin adreslerde... C'de bu duruma izin var... Bu gibi farklılıklara dikkat edilerek sanırım hepsi kullanılabiliyor...

C bilmediğim için bu konuya yorum yapamayacağım :)
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

sem

Evet doğru diyorsunuz... Benim aklım doğrudan ctrl + C ve ctrl + Z'ye gitti... Alışkanlıktan olsa gerek... Ben aslında şifre girme olayının enter ile sonlanmasını demiştim daha makul diye fakat sizin de dediğiniz gibi sadece örnek olarak gönderilen kod için üzerinde durulacak bir konu bile değil.. Yine dediğiniz gibi mantığını anladıktan sonra istenilen şekilde uyarlaması daha zaten kolay olacaktır.

Yani evet, katılıyorum size... Programın ** karakter basması durumuna hiç dikkat etmememiştim...



Demek istediğim "extern C" olarak değildi... Fonksiyonları olduğu gibi kullanabilmekten bahsetmiştim daha çok...  Yani yukarıdaki kodu, örnek olarak göndermiş olduğum programcığı;

gcc program.c -o program


ya da

g++ program.c -o program

şeklinde her iki türlü derlenebileceği tarzındaydı daha çok demek istediğim...

Yorum yapmadığnız konu ise sadece örnek vermiştim... Yani fonksiyonları C ya da C++ her ikisinde de kullanabilyioruz; fakat aralarında bazı farklılıklar var dedim =) Yani o da çok üzerinde durulacak bir şey değil... =)
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?