İçeriğe geç
ShiftDelete.Net
Haber ara/ SDN'ye SorGiriş
Haber Akışı SDNTV İnceleme Forum Yapay Zeka Akıllı Telefon Elektrikli Otomobil Oyun ShiftDelete.Net Global Teknoloji Haberleri Mobil Otomobil Donanım Savunma Bilim Sosyal Medya İnternet Giyilebilir Teknoloji Rehber Ürünler Son dakika Yazarlar
  1. Ana sayfa
  2. Topluluk
  3. Programlama
  4. Programlama Dilleri
Programlama Dilleri

C Dilinde Parametre Olarak String İçinde String Gönderme

Ben Kenobi22.01.20126 cevap7.519 görüntüleme
#1
Arkadaşlar uzun süredir sormak istiyorum aslında.
Bir örnek vereyim.

char *deneme;
printf("Bir seyler yaziniz\n");
gets(deneme);
printf("bu metnin degerini %s stringi belirler",deneme);


Burada gördüğünüz printf fonksiyonunun güzel bir özelliği sayesinde yazdığımız metin içerisinde değişken bir string atıyoruz.
Şimdi ise bir fonksiyon düşünelim


void fonksiyon(char[]);
int main()
{
    fonksiyon("bu metnin degerini %s stringi belirler",deneme)
    return 0;
}


Burada bir stringin orta yerine başka bir string eklemem gerek.
Yani string içinde string gönderiyorum parametre olarak.
Yukarıdaki gibi olmuyor elbet çünkü fonksiyon başta tek parametreli olarak tanımlanmıştı.
Yardımlarınızı bekliyorum.
Cevaplar
#2
Selam;

Bu dedgini iki sekilde yapabilirsin .

1. Yol: Zaten char array parametre kabul ediyorsun , gonderdigin elemanlari bir arrayin icerisine atarak gonderebilirsin ,
Ornegin:

void benim_fonksiyonum(char **dizi_parametre);

int main()
{
char **dizi;
char * deneme;
char *cumle_icinde_cumle= "benim cumlemde %s var";
dizi = (char **)malloc(2*sizeof(char *));
gets(deneme);

dizi[0] = cumle_icinde_cumle;
dizi[1] = deneme;
benim_fonksiyonum(dizi);
}


Yukaridaki ornek (syntax hatasi olabilir) string dizisi olusturup bunu parametre olarak gonderebilmeni saglar, istersen benim_fonksiyonuma bir int n parametresi ekleyim kac eleman gonderdiginide belirtebilirsin.
benim_fonksiyonum(2,dizi);
gibi.

2. Yol: C veya C++ ta degisken sayili parametre gonderebilirsin tipki printf fonksiyonunda oldugu gibi , bunun icin stdarg.h dosyasini include etmen lazim.

Ornek


#include <stdio.h> #include <stdarg.h> 
void benim_fonksiyonum(int n,...) {
va_list listem;
int i;

va_start(listem, n);
for(i= 0; i< n; i++) {
   printf("Yeni bir degisken %s\n",va_arg(listem,char *));
}
va_end(listem);

}


Yukaridaki va_ ile baslayan fonksiyonlar gercekte birer marodur. Degisken sayili fonksiyonlar en az bir tane tanimli ilk degiskene sahip olmalidir. Bu degisken int yerine stringte olabilir tipki printf te oldugu gibi.

Iyi calismalar
#3
char *deneme;
gets(deneme);

Bir işaretçiyi bu şekilde direkt olarak kullanamazsın. Önce bellek tahsisi yapmalı ve adresini almalısın.

char *deneme = (char) malloc(50);
gets(deneme);

Veya kestirmeden bir dizi.
char deneme[50];
gets(deneme);

String içindeki %s gibi belirteçler string e özel birşey değildir. Bunları printf ve scanf fonksiyonları özel olarak yorumlar. Yani kendi yazdığınız bir fonksiyona bu şekilde argüman olarak gönderemezsiniz.

Ayrıca printf("bu metnin degerini %s stringi belirler",deneme);
ifadesi bir stringin içine diğerini eklemez veya yeni bir tane oluşturmaz. Sadece verilen stringi farklı bir formda ekrana yazar. Şöyle bir kod deneyebilirsiniz daha iyi anlamak açısından.

char *str = "Bu %s bir %d string'dir.";
printf("%s", str);

Bu string olduğu gibi yazılacaktır. % işaretleri herhangi bir değişime uğramaz.

Sorunuzun cevabına gelince;
Bu işi yapan hazır fonksiyon kullanmak en iyisi ama aradım bulamadım öyle bişey. O yüzden kendim karalayıverdim bişeyler. Aşağıdaki fonksiyon verilen bir string deki '_' karakterinin yerine diğer stringi koyar. (Tıpkı printf teki % gibi). Tabi yeteri kadar ayrılmış bellek olması kullanıcının sorumluluğunda.

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

void stringYerlestir(char *str, const char *icine)
{
    char temp[100];
    int i = 0;
    
    while(str[i++] != '_');
    
    strcpy(temp, &str[i]);
    strcpy(&str[--i], icine);
    strcat(str, temp);
}

int main()
{
    char str[100] = "Merhaba _ dunya";
    char sub[30] = "yalan";

    stringYerlestir(str, sub);
    printf("%s\n", str);
    
    return 0;
}
#4
Amenofis dedi: ↑
char *deneme;
gets(deneme);

Bir işaretçiyi bu şekilde direkt olarak kullanamazsın. Önce bellek tahsisi yapmalı ve adresini almalısın.

char *deneme = (char) malloc(50);
gets(deneme);

Yukarida yazdigin dogru, benim yazdigim orneklerde amac pointer kullanimi yada nasil string okunacagini gostermek olmadigindan uzerinde durmadim, yinede aciklayici ve yanlis anlamalari giderici oldugu icin dedigine katiliyor tesekkur ediyorum.

Veya kestirmeden bir dizi.
char deneme[50];
gets(deneme);

String içindeki %s gibi belirteçler string e özel birşey değildir. Bunları printf ve scanf fonksiyonları özel olarak yorumlar. Yani kendi yazdığınız bir fonksiyona bu şekilde argüman olarak gönderemezsiniz.

Burada yazdigin sey ise tam olarak dogru degil, %s ozel birsey olmamakla beraber yukarida yine benim anlattigim gibi kendi fonksiyonuna parametre olarak gonderebilirsin. Burada muhim olan %s i kendi fonksiyonun icerisinde yorumlaman gerektigi.

Ayrıcaprintf("bu metnin degerini %s stringi belirler",deneme);
ifadesi bir stringin içine diğerini eklemez veya yeni bir tane oluşturmaz. Sadece verilen stringi farklı bir formda ekrana yazar. Şöyle bir kod deneyebilirsiniz daha iyi anlamak açısından.

Benim arkadasin sorusundan anladigim, printf teki gibi nasil string icerisinde paramtre gonderebiliriz vs vs idi, eger amac senin dedigin gibi ise ic ice bir kac strcat ile zaten birbirine eklenebilir diye dusunuyorum.


char *str = "Bu %s bir %d string'dir.";
printf("%s", str);

Bu string olduğu gibi yazılacaktır. % işaretleri herhangi bir değişime uğramaz.

Evet ama yapilmak isteenen bu degil diye dusunuyorum.

Sorunuzun cevabına gelince;
Bu işi yapan hazır fonksiyon kullanmak en iyisi ama aradım bulamadım öyle bişey. O yüzden kendim karalayıverdim bişeyler. Aşağıdaki fonksiyon verilen bir string deki '_' karakterinin yerine diğer stringi koyar. (Tıpkı printf teki % gibi). Tabi yeteri kadar ayrılmış bellek olması kullanıcının sorumluluğunda.

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

void stringYerlestir(char *str, const char *icine)
{
    char temp[100];
    int i = 0;
    
    while(str[i++] != '_');
    
    strcpy(temp, &str[i]);
    strcpy(&str[--i], icine);
    strcat(str, temp);
}

int main()
{
    char str[100] = "Merhaba _ dunya";
    char sub[30] = "yalan";

    stringYerlestir(str, sub);
    printf("%s\n", str);
    
    return 0;
}
Nasil parca parca alinti yapilacagini bilmedigimden, benim yazdiklarimi yukarida koyu olarak isaretledim.
Iyi calismalar
#5
İstediğn şeyi sprintf kullanarak şu şekilde yapabilirsin;
char buffer [50];
int n;
char deneme[10];
printf("Bir seyler yaziniz\n");
gets(deneme);
n=sprintf (buffer, "bu metnin degerini %s stringi belirler", deneme);
printf ("[%s]",buffer);
fonksiyon(buffer);
Ben Kenobi Konuyu açan
#6
Amenofis dedi: ↑
char *deneme;
gets(deneme);

Bir işaretçiyi bu şekilde direkt olarak kullanamazsın. Önce bellek tahsisi yapmalı ve adresini almalısın.

char *deneme = (char) malloc(50);
gets(deneme);

Veya kestirmeden bir dizi.
char deneme[50];
gets(deneme);

String içindeki %s gibi belirteçler string e özel birşey değildir. Bunları printf ve scanf fonksiyonları özel olarak yorumlar. Yani kendi yazdığınız bir fonksiyona bu şekilde argüman olarak gönderemezsiniz.

Ayrıcaprintf("bu metnin degerini %s stringi belirler",deneme);
ifadesi bir stringin içine diğerini eklemez veya yeni bir tane oluşturmaz. Sadece verilen stringi farklı bir formda ekrana yazar. Şöyle bir kod deneyebilirsiniz daha iyi anlamak açısından.

char *str = "Bu %s bir %d string'dir.";
printf("%s", str);

Bu string olduğu gibi yazılacaktır. % işaretleri herhangi bir değişime uğramaz.

Sorunuzun cevabına gelince;
Bu işi yapan hazır fonksiyon kullanmak en iyisi ama aradım bulamadım öyle bişey. O yüzden kendim karalayıverdim bişeyler. Aşağıdaki fonksiyon verilen bir string deki '_' karakterinin yerine diğer stringi koyar. (Tıpkı printf teki % gibi). Tabi yeteri kadar ayrılmış bellek olması kullanıcının sorumluluğunda.

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

void stringYerlestir(char *str, const char *icine)
{
    char temp[100];
    int i = 0;
    
    while(str[i++] != '_');
    
    strcpy(temp, &str[i]);
    strcpy(&str[--i], icine);
    strcat(str, temp);
}

int main()
{
    char str[100] = "Merhaba _ dunya";
    char sub[30] = "yalan";

    stringYerlestir(str, sub);
    printf("%s\n", str);
    
    return 0;
}
Benim yaptığım şekilde gayet kullanılabilir.
Her yerde kullanılamaz elbet.
Mesela birtakım dosya işlemleri sonucu alınan pointer değişkenlerde mutlaka malloc ile dinamik bellek tahsis etmek gerekir.
Ancak benim örnekteki gibi basit durumlarda pointer zaten her yeni gelen bilgiyi bir öncekini kaydırarak yerleştirdiği için bir sorun teşkil etmez.
Ayrıca malloc işlemciye ekstra yük bindireceği için hata oluşmadığı takdirde benim yaptığım şekilde kullanmak daha mantıklıdır.
Veya en azından ben öyle biliyorum :D
#7
Yanlış biliyorsun. Bunlar hayati hatalar, fatal error! Bu konuları iyice anlamadan devam etme bence.

Herhangi bir değişkene bir değer atamazsan içindeki çöp değerdir, yani rastgele. Pointer da aynı şekilde, üstelik pointer lar adres taşıdıklarına göre bu rastgele bir adres demektir.

char *deneme;
*deneme = 100;

Şimdi biz bellekte rastgele bir yere 100 yazdık. Eğer bu yazdığımız yer işletim sistemi tarafından başka bir program için tahsis edildi ise program çalıştığı an hata verip sonlanır.

Yok eğer kullanılmayan bir yer ise başlangıçta hata vermeyebilir (duruma göre değişir, yani şans!) fakat o adresi iş. sisteminin bilgisi dışında kullandığımızdan, başka bir program (hatta kendi programımız) bellek isteğinde sistem bizim kullandığımız bölgeyi verebilir ve bunun sonucunda verimiz kaybolur. Orayı kullanmak istediğimizde tekrar fatal error!

Fakat;
deneme = (char) malloc(1); dersek artık o 1 bayt bizimdir. Hiçbir şekilde başka bir programa verilmez ve güvenle kullanabiliriz.

Cevabını yaz

Cevap yazmak için giriş yap ya da üye ol. Eski forum kullanıcı adın ve parolanla girebilirsin.