Picproje Elektronik Sitesi

SERBEST BÖLGE => Programlama ve Algoritma => Konuyu başlatan: baran123 - 25 Haziran 2015, 20:58:58

Başlık: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 25 Haziran 2015, 20:58:58
Strcat iş görüyor ama dipten nasıl yapılır onu öğrenmek istiyorum.


static char MyText[32];

// daha float değerleri string yapıyorum
static void FloatToString(float f)
{
    sprintf(MyText, "%4.3f", f);
}

//sonra şöyle kullanıyorum
USART_SendString(USART2, strcat(MyText, "\r\n"));

//usart string de bu şekilde
static void USART_SendString(USART_TypeDef* USARTx, char* s)
{
    while(*s)
    {
        while(!(USARTx ->SR & 0x00000040));
        USART_SendData(USARTx, *s);
        s++;
    }
}

Bu string in sonuna ""\r\n" ekleme işlemini nasıl yapabiliriz ?
Aslında string yanlış oldu char dizisinin sonuna nasıl eklerim :)
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Klein - 25 Haziran 2015, 22:43:38
sprintf ile çevirirken yapabilirdiniz


sprintf(MyText, "%4.3f\r\n", f);


illa bu şekilde yapmayacağım kendim yapacağım derseniz
karakter dizisinde  0 görene kadar ilerleyin. 0 gördüğünüz adrese "\r"  bir sonra kine "\n" bir sonrakinde de "\0" koyun.

Ek:
Könderme rutininde zaten dizinin sonuna kadar ilerliyorsunuz. Dizinin sonu geldikten sonra da koyabilirsiniz.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 25 Haziran 2015, 22:48:18
Ön bilgi:
Bir dizinin içinde kaç eleman var bunu öğrenmek:
bir while döngüsü içinde, array'in bütün elemanlarına sırayla bakılır ve bu sırada bir sayaç mütemadiyen artırılır. Ta ki eleman 0(yazıyla: sıfır) olana kadar.

fonksiyon prototipimiz böyle olacak:
void KatarBirlestir(char *katar, char *eklenecekKatar2);
ilk katarın adresini ve eklenecek olan katar'ın adresini veriyoruz.
Sonra ilk katarın kaç karakter barındırdığını, yukarda anlattığım yöntemle buluyoruz.
Aynı işlemi ikinci katar için de yapıyoruz.
Sonra ikinci elemanın karakter sayısı kadar bir for döngüsü kuruyoruz.
For'un her adımında, ilk katarın adresini bir artırarak, ikinci katardaki elemanları birer birer ekliyoruz.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 25 Haziran 2015, 23:43:00
@Klein hocam evet öylede oldu.

static void USART_SendString(USART_TypeDef* USARTx, char* s)
{
    while(*s)
    {
        while(!(USARTx ->SR & 0x00000040));
        USART_SendData(USARTx, *s);
        s++;
    }
    USART_SendData(USARTx, '\r');
    USART_SendData(USARTx, '\n');
}


@Gökhan hocam bir de dediğiniz gibi yapmaya çalışayım bir de
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 26 Haziran 2015, 00:44:36
Benim dediğimi yaparsan arkaplanda ne yaptığını daha iyi anlarsın. İlerde karşılaşacağın sorunların sebebini anlarsın bir bakışta.
Ama program yazarken ben de sprint kullanıyorum pratik olduğu için.
Mottomuz: öğren ama kullanma...
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: muhittin_kaplan - 26 Haziran 2015, 00:47:55
sprint i neden kullanma ?
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 26 Haziran 2015, 00:51:31
Biraz daha çözeyim sprintfi de kendim yazacam.

Hocam uğraşıyorum da fonksiyon prototipinde hata var diyor ve işaretini gösteriyor ?
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 26 Haziran 2015, 00:53:13
Onu demek istemedim hocam, "fonksiyonların nasıl çalıştığını öğrenmek için kendi fonksiyonlarını yaz ama, yine sprintf gibi hazır fonksiyonları kullan, pratik olsun" anlamında dedim.

mesaj birleştirme:: 26 Haziran 2015, 00:54:26

Baran & yerine * yaz düzelir. Yanlışlıkla öyle yazmışım şimdi düzelttim.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 26 Haziran 2015, 01:16:30
Hocam şöyle bir şey denedim ama beceremedim sanırım


static char MyText[32];

static void KatarBirlestir(char* katar1, char* katar2)
{
    unsigned int sayac1 = 0;
    unsigned int sayac2 = 0;

    while(*katar1 != '\0')
    {
        katar1++;
        sayac1++;
    }

    while(*katar2 != '\0')
    {
        katar2++;
        sayac2++;
    }
    unsigned int i;

    for(i = 0;i < sayac2; i++)
    {
        katar1[sayac1 + i] = *katar2;
    }
}

KatarBirlestir(MyText, "\r\n");
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 26 Haziran 2015, 02:39:35
Çalışmaması normal @Baran Ekrem 
while içinde artırdığın kısım varya kilit noktası orası.
katar1++; yaptığın zaman, o göstericinin gösterdiği yer de sürekli artıyor.
ve aşağıdaki for'a geldiğin zaman o son değerlere göre işlem yapıyor.

Şöyle bir düzenleme yaptım aklımca, ama denemedim, bir dene istersen:


char MyText[32]="ilk Katar , \0";
char MyText2[32]="ikinci Katar , \0";

static void KatarBirlestir(char* katar1, char* katar2)
{
    unsigned int sayac1 = 0;
    unsigned int sayac2 = 0;

    while(*(char *)(katar1+sayac1) != '\0')
    {
        sayac1++;
    }

    while(*(char *)(katar2+sayac2) != '\0')
    {
        sayac2++;
    }
    unsigned int i;

    for(i = 0;i < sayac2; i++)
    {
        katar1[sayac1 + i] = *katar2;
    }
}

KatarBirlestir(&MyText[0],&MyText2[0]);



mesaj birleştirme:: 26 Haziran 2015, 02:43:05

Bu arada belirtiyim, bu fonksiyonu uzun uzun yazdık ama normalde bunu çok daha kısa kodlarla da yapabilirsin. Normal çalışma mantığını anladıktan sonra optimize üzerine çalışır en kısa şekilde halletmeye odaklanırsın.

düzeltme: pointer'daki yazım hatası düzeltildi.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 26 Haziran 2015, 02:56:44
Hocam şu kısmı anlamadım
while(*(char)(katar1+sayac1) != '\0') burada hata veriyor. sanırım sayac int olduğu için
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 26 Haziran 2015, 03:03:22
Şu an deneyemiyorum char kısmını silip deneyebilirsin.
ya da şöyle dene:
while(*((char*) katar1+sayac1)!= '\0')
(şu an ne saçmaladığımı bilmiyorum, uykuluyum)
Ordaki amacımız, katar1 adresinin sayac1 kadar fazlası olan adresi okumak ve okuduğumuz değerin 0'a eşit olup olmadığı sürece döngüye sokmak.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: CLR - 26 Haziran 2015, 03:56:11
Aşağıdaki gibi dene çalışacaktır


typedef unsigned char u8;
typedef const unsigned char  uc8;

u8 * MyStrCat(u8 *s, uc8 *Add)
{
    u8 *Ret=s;
    while(*s)  s++; // string sonuna git
    while(*s++ = *Add++); // ekle
    return Ret;
}

örnek:
u8 Ms[20]="Merhaba";

puts(MyStrCat(Ms," Kardes"));

// ekrana "merhaba kardes" basacaktır

Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mufitsozen - 26 Haziran 2015, 08:15:55
hedef yada sonuc(destination) dizin'in (string) boyunun yeterli olmadigi durumlarda cikabilecek kotu hatalari onlemek icin ben strncat kullanmanizi tavsiye edecegim.

bunun standard kaynak kodu:
#include <stddef.h> /* size_t */
char *strncat(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    while (*dest)
        dest++;
    while (n--)
        if (!(*dest++ = *src++))
            return ret;
    *dest = 0;
    return ret;
}

yada daha sikistirilmis hali ile:

#include <stddef.h> /* size_t */
char *strncat(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    while (*dest) dest++;
    while (n--)  if (!(*dest++ = *src++)) return ret;
    *dest = 0;
    return ret;
}
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 26 Haziran 2015, 10:30:13
Programdaki hataları giderdim @Baran Ekrem

#include <stdio.h>

char MyText[32]="ilk Katar , \0";
char MyText2[32]="ikinci Katar\0";

void KatarBirlestir(char* katar1, char* katar2);

int main(void)
{
KatarBirlestir(&MyText[0],&MyText2[0]);

printf("sonuc: %s",&MyText[0]);
       
        printf("\r\nislem tamam");
char asdasda;
scanf("%c",&asdasda); //getchar();   
    return 0;
}


void KatarBirlestir(char* katar1, char* katar2)
{
    unsigned int sayac1 = 0;
    unsigned int sayac2 = 0;

    while(*(char *)(katar1+sayac1) != '\0')
    {
        sayac1++;
    }

    while(*(char *)(katar2+sayac2) != '\0')
    {
        sayac2++;
    }
    unsigned int i;

    for(i = 0;i < sayac2; i++)
    {
        katar1[sayac1 + i] = *(char *)(katar2+i);
    }
}
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mir_as82 - 26 Haziran 2015, 12:42:09
Alıntı yapılan: mufitsozen - 26 Haziran 2015, 08:15:55
hedef yada sonuc(destination) dizin'in (string) boyunun yeterli olmadigi durumlarda cikabilecek kotu hatalari onlemek icin ben strncat kullanmanizi tavsiye edecegim.

bunun standard kaynak kodu:
#include <stddef.h> /* size_t */
char *strncat(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    while (*dest)
        dest++;
    while (n--)
        if (!(*dest++ = *src++))
            return ret;
    *dest = 0;
    return ret;
}

yada daha sikistirilmis hali ile:

#include <stddef.h> /* size_t */
char *strncat(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    while (*dest) dest++;
    while (n--)  if (!(*dest++ = *src++)) return ret;
    *dest = 0;
    return ret;
}

Hocam senin verdiğin kodu anlamaya çalıştım acaba yanlış mı anladım sorayım dedim. Bu kodda hedef stringin(dest) içinde birde fazla Null karakter olabilir mi?
Az önce tekrar baktım son While ın döngüsünün kapsamını yanlış anlamışım. : ).  n değeri iki stringin toplamından küçükse birleştirme tamamlanmıyor ve sonuna Null karakter koyup çıkılıyor
Veya n in tamamlanmasını beklemeden source stringin sonunda null görünce çıkıyor
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mufitsozen - 26 Haziran 2015, 12:43:18
Alıntı yapılan: mir_as82 - 26 Haziran 2015, 12:42:09
Hocam senin verdiğin kodu anlamaya çalıştım acaba yanlış mı anladım sorayım dedim. Bu kodda hedef stringin(dest) içinde birde fazla Null karakter olabilir mi?

null derken \0 (0x00) kastediliyorsa hayir. cunku 0x00 dizin sonunu gosterir.

Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mir_as82 - 26 Haziran 2015, 12:52:59
Ama klas bir kodlama. İnşallah ileride bende bunun gibi kodlama yapabilirim. Hala süslü parantez aç-kapat yapmaktan vazgeçemiyorum.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mufitsozen - 26 Haziran 2015, 19:38:11
Alıntı yapılan: mir_as82 - 26 Haziran 2015, 12:52:59
Ama klas bir kodlama. İnşallah ileride bende bunun gibi kodlama yapabilirim. Hala süslü parantez aç-kapat yapmaktan vazgeçemiyorum.

her turlu tasarimda zerafet(elegance) sadelikten gecer diye bir dusunce var.

Bauhaus design school diye bakarsan mimari vs ornekleri gorursun https://www.google.com.tr/search?q=minimalism&newwindow=1&biw=1257&bih=612&source=lnms&tbm=isch&sa=X&ei=f36NVaW_G8a6sQHS96DYDQ&ved=0CAYQ_AUoAQ#newwindow=1&tbm=isch&q=bauhaus+design (https://www.google.com.tr/search?q=minimalism&newwindow=1&biw=1257&bih=612&source=lnms&tbm=isch&sa=X&ei=f36NVaW_G8a6sQHS96DYDQ&ved=0CAYQ_AUoAQ#newwindow=1&tbm=isch&q=bauhaus+design).

(yada minimalism https://www.google.com.tr/search?q=minimalism&newwindow=1&biw=1257&bih=612&source=lnms&tbm=isch&sa=X&ei=f36NVaW_G8a6sQHS96DYDQ&ved=0CAYQ_AUoAQ (https://www.google.com.tr/search?q=minimalism&newwindow=1&biw=1257&bih=612&source=lnms&tbm=isch&sa=X&ei=f36NVaW_G8a6sQHS96DYDQ&ved=0CAYQ_AUoAQ)

Bu akim 1960lar ve 70lerde Amerikada cok yogundu, hala da yogun. C, ve Unix yaraticilari bu akimlardan cok etkilendiler. Bu yuzden Unix ve C'nin yaraticilari bu ortamlari bir takim kurallar uzerine kurdular. Ornegin KISS prensibi bunlardan bir tanesidir (KISS= Keep It Simple, Stupid) Bununla ilgili bir aciklama apache web sitesinde var https://people.apache.org/~fhanik/kiss.html (https://people.apache.org/~fhanik/kiss.html)

Ayrica C ve Unix'i tasarlayanlar bu ortami kullananlarin muhakkak bilgisayardan anlayan kimseler oldugunu dusunerek, az mesaj veren, sadece bir isi iyi yapan kucuk program parcalarinin birinden oburune bilginin akisini saglayan bir yapi gibi yapisal tasarimlar yaptilar. Cok verilen bir ornek (http://41.media.tumblr.com/77017ba31fb28c52314e9e29b6d75ea3/tumblr_nf4f6p0NUN1qavt6co1_1280.jpg)

Bu konuda yazilmis kitaplar vb bile vardir. Kisa bir ozet yaparsak bu prensiplerden bazisi:

    Small is beautiful.

    Make each program do one thing well.

    Build a prototype as soon as possible.

    Choose portability over efficiency.

    Store numerical data in flat ASCII files.

    Use software leverage to your advantage.

    Use shell scripts to increase leverage and portability.

    Avoid captive user interfaces.

    Make every program a filter.

C Standard library'deki fonksiyonlarin buyuk bir bolumu bu prensipler uzerine kuruludur. (ornegin o yuzden strcat return degeri olarak dest string ptr kullanir, bu sekilde ayni satirda ic ice strcat kullanarak bir suru dizini birbirine ekleyebilirsiniz). yada strncat eger ekleme isleminde alan dizinin boyu yetmezse hicbir hata kodu vermez, cunku programci bunun olmayacagini zaten baska bir sekilde garanti etmistir diye dusunur, vs vs

Iste buda 1970lerden onemsiz bir kac ani. Unutulmus tarih gibi :-)
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 26 Haziran 2015, 21:52:16
Tamamdır teşekkürler herkese :)
Şu bayağı şaşırttı :D
Alıntı yapılan: CLR - 26 Haziran 2015, 03:56:11
Aşağıdaki gibi dene çalışacaktır


typedef unsigned char u8;
typedef const unsigned char  uc8;

u8 * MyStrCat(u8 *s, uc8 *Add)
{
    u8 *Ret=s;
    while(*s)  s++; // string sonuna git
    while(*s++ = *Add++); // ekle
    return Ret;
}

örnek:
u8 Ms[20]="Merhaba";

puts(MyStrCat(Ms," Kardes"));

// ekrana "merhaba kardes" basacaktır


Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: CLR - 27 Haziran 2015, 01:51:42
@Baran Ekrem

Niçin şaşırdın?  :)
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: baran123 - 27 Haziran 2015, 01:55:43
Bu kadar kısa beklemiyordum. :)
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mufitsozen - 27 Haziran 2015, 07:51:34
Alıntı yapılan: Baran Ekrem - 27 Haziran 2015, 01:55:43
Bu kadar kısa beklemiyordum. :)

minimalizm felsefesi :-)

Aslinda C Standard library Wikisinden buradaki baska fonksiyonlara da bakip nasil calistiklarina bakarsan C'yi amaclandigi gibi kullanan bir stilde ogrenirsin.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: sovalye - 27 Haziran 2015, 22:14:48

#include <stdio.h>
#include <stdlib.h>

char* birleştir(char *s1, char* s2){
    int i1 = 0, i2 = 0, j;
    while (s1[i1] != '\0') i1++;
    while (s2[i2] != '\0') i2++;
    char *toplam = (char*)malloc(sizeof(char)*(i1+i2+1));
    for (j = 0; j < i1; j++)
        *(toplam + j) = s1[j];
    for (; j < i1+i2; j++)
        *(toplam + j) = s2[j - i1];
    toplam[j] = '\0';
    return toplam;

}

int main(void){
    int i = 0;
    char *yazi1 = "selam";
    char *yazi2 = "naber";
    yazi1 = birleştir(yazi1, yazi2);
    printf("%s", yazi1);
    free(yazi1);
    return 0;
}


İlk başta büyük boyutlu dizi tanımlamaktan kurtulmak için veya birleştirilecek dizilerin boyutu hakkında bir bilgin olmazsa işlemi bu şekilde de yapabilirsin.
Edit: hatirlatma üzerine free ekledim.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: mir_as82 - 28 Haziran 2015, 00:54:31
Hocam aldigin yeri free lemen gerekiyor muydu? Main fonksiyonu içinde ?
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: Gökhan BEKEN - 28 Haziran 2015, 01:54:46
Güzel mantık ama malloc komutu her platformda kullanılamıyor benim bildiğim.
Başlık: Ynt: C de string birleştirme.(Strcat kullanmadan)
Gönderen: sovalye - 28 Haziran 2015, 12:01:42
@mir_as82  doğru söylüyorsunuz hocam. Hızlı yazıyım dedim, belleği geri vermeyi unutmuşum.
@Gökhan BEKEN tüm platformlar destekliyor diye biliyorum. Ccs c bile destekliyor.