Neden alt dizimi yönlendiren garip karakterler alıyorum?

C içinde herhangi bir karakter dizisinin alt dizesini döndüren bir işlev yaratmaya çalışıyorum. Bana doğru çıktının çoğunu veriyor, ama aynı zamanda dizenin başında bazı tuhaf karakterler de alıyorum. Örneğin, "abcdefg" girişi verildiğinde ve 3 ila 5 karakterlerinde istendiğinde, bana "WvWdef" değerini verir. Öyle görünüyor ki g düzgün bir şekilde kesiliyor, ancak görmezden gelmek yerine ilk 3 karaktere garip bir şey yapıyorum. Kodum aşağıda yer almaktadır:

typedef char * String;
String subStr(String src, int start, int end){

   if ((start > (strLen(src)-1)) || start < 0 || end < start ||
        (end > (strLen(src) - 1)) ){
       return NULL;
   }
   int s = start, e = end;
   String r = (String)malloc((e - s + 1) * sizeof(char));

   while(s <= e){
       r[s] = src[s];
       s++;
   }
   r[s] = '\0';

   return r;
} 
0
bu satırla ilgili: 'String r = (String) malloc ((e - s + 1) * sizeof (char));' 1) C 'de, döndürülen değeri malloc'tan (ve işlevler ailesinden) almayın. 2) işlemin başarılı olduğundan emin olmak için kullanmadan önce, döndürülen değeri daima kontrol edin (! = NULL). 3) sizeof (char) her zaman 1'dir, bu nedenle 1 ile çarpılması kod kaybıdır. '* sizeof (char)' ifadesini kaldırmanızı öneririz
katma yazar user3629249, kaynak
start == end ise, malloc açıkça 1 karakter çok kısadır. bu, başlangıç ​​ve bitiş arasındaki mesafeden bağımsız olarak uygulanır. 'S' en son artırıldığında ve sonra '\' işaretinin bulunduğu yere '\ 0' atanması, tahsis edilen ara belleğin sonundan geçiyor. Bu tanımlanamayan davranışla sonuçlanır ve seg defası olayına yol açabilir/açabilir
katma yazar user3629249, kaynak
's', 'r []' dengesi olarak kullanıldığında, kopyalanan verilerin 'r []' dizisinin sonundan yazacağı anlamına gelir, 'start = 0'
katma yazar user3629249, kaynak
's', 'r []' dengesi olarak kullanıldığında, kopyalanan verilerin 'r []' dizisinin sonundan yazacağı anlamına gelir, 'start = 0'
katma yazar user3629249, kaynak

9 cevap

Şurada bir mantık hatası var:

while(s <= e){
   r[s] = src[s];
   s++;
}

src dizini doğrudur. Ancak r dizini değil. Başka bir dizine ihtiyacın var.

i = 0;
while(s <= e){
   r[i] = src[s];
   s++;
   i++
}

Döngüden sonra, yerine:

r[s] = '\0';

kullanın:

r[i] = '\0';

Ayrıca malloc kullanarak ayrılacak karakter sayısında mantık hatası var.

s = 3 ve e = 5 alındığında, src [3] , src [4] 'den oluşan bir dize döndürüyorsunuz. , src [5] . Bu 3 karakterdir. Sonlandırıcı boş karakteri eklediğinizde, 4 karaktere ihtiyacınız vardır. (e - s + 1) yalnızca 3 değerini verir. Bunun yerine (e - s + 2) tuşunu kullanın.

2
katma
'R Sahu' nun gösterdiği hataya ek olarak, start ve end 'in bir/inclusive/range olmasını düşünüyorsanız, malloc'unuz Bir karakter/az/gerekenden daha az. Alternatif olarak, yarı açık bir aralık ('standart' yol) olması niyetindeyseniz, while döngüsü durumunuz iken (s yani katı eşitsizliğe gitmelidir.
katma yazar Happy Green Kid Naps, kaynak

Şurada bir mantık hatası var:

while(s <= e){
   r[s] = src[s];
   s++;
}

src dizini doğrudur. Ancak r dizini değil. Başka bir dizine ihtiyacın var.

i = 0;
while(s <= e){
   r[i] = src[s];
   s++;
   i++
}

Döngüden sonra, yerine:

r[s] = '\0';

kullanın:

r[i] = '\0';

Ayrıca malloc kullanarak ayrılacak karakter sayısında mantık hatası var.

s = 3 ve e = 5 alındığında, src [3] , src [4] 'den oluşan bir dize döndürüyorsunuz. , src [5] . Bu 3 karakterdir. Sonlandırıcı boş karakteri eklediğinizde, 4 karaktere ihtiyacınız vardır. (e - s + 1) yalnızca 3 değerini verir. Bunun yerine (e - s + 2) tuşunu kullanın.

2
katma
'R Sahu' nun gösterdiği hataya ek olarak, start ve end 'in bir/inclusive/range olmasını düşünüyorsanız, malloc'unuz Bir karakter/az/gerekenden daha az. Alternatif olarak, yarı açık bir aralık ('standart' yol) olması niyetindeyseniz, while döngüsü durumunuz iken (s yani katı eşitsizliğe gitmelidir.
katma yazar Happy Green Kid Naps, kaynak

Şurada bir mantık hatası var:

while(s <= e){
   r[s] = src[s];
   s++;
}

src dizini doğrudur. Ancak r dizini değil. Başka bir dizine ihtiyacın var.

i = 0;
while(s <= e){
   r[i] = src[s];
   s++;
   i++
}

Döngüden sonra, yerine:

r[s] = '\0';

kullanın:

r[i] = '\0';

Ayrıca malloc kullanarak ayrılacak karakter sayısında mantık hatası var.

s = 3 ve e = 5 alındığında, src [3] , src [4] 'den oluşan bir dize döndürüyorsunuz. , src [5] . Bu 3 karakterdir. Sonlandırıcı boş karakteri eklediğinizde, 4 karaktere ihtiyacınız vardır. (e - s + 1) yalnızca 3 değerini verir. Bunun yerine (e - s + 2) tuşunu kullanın.

2
katma
'R Sahu' nun gösterdiği hataya ek olarak, start ve end 'in bir/inclusive/range olmasını düşünüyorsanız, malloc'unuz Bir karakter/az/gerekenden daha az. Alternatif olarak, yarı açık bir aralık ('standart' yol) olması niyetindeyseniz, while döngüsü durumunuz iken (s yani katı eşitsizliğe gitmelidir.
katma yazar Happy Green Kid Naps, kaynak

Malloc ile bir bellek bloğu ayırdığınızda, herhangi bir şeyle doldurulabilir, bu yüzden başlangıçta sıfır yazmanız gerekir.

bzero(r,e-s+1);

ayrıca indeks s değil de indeks 0'dan r'ye kopyalamaya başlamak istersiniz. Her ikisi için de s kullanmamalısınız.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
katma
bu, çıkartılacak bayt sayısının 1’ini kopyalayacaktır. (start == end ise, yine de bir bayt kopyalamanız gerekir. 'r []' içindeki her byte yazılacağından, onu başlatmanız gerekmez (hata ayıklamayı kolaylaştırmak dışında) ve malloc'ların bayt sayısı '\ 0' baytının izlenmesi için yer olması gerektiği için çok kısa
katma yazar user3629249, kaynak
düzeltildi, teşekkürler.
katma yazar Stewart Grant, kaynak

Malloc ile bir bellek bloğu ayırdığınızda, herhangi bir şeyle doldurulabilir, bu yüzden başlangıçta sıfır yazmanız gerekir.

bzero(r,e-s+1);

ayrıca indeks s değil de indeks 0'dan r'ye kopyalamaya başlamak istersiniz. Her ikisi için de s kullanmamalısınız.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
katma
bu, çıkartılacak bayt sayısının 1’ini kopyalayacaktır. (start == end ise, yine de bir bayt kopyalamanız gerekir. 'r []' içindeki her byte yazılacağından, onu başlatmanız gerekmez (hata ayıklamayı kolaylaştırmak dışında) ve malloc'ların bayt sayısı '\ 0' baytının izlenmesi için yer olması gerektiği için çok kısa
katma yazar user3629249, kaynak
düzeltildi, teşekkürler.
katma yazar Stewart Grant, kaynak

Malloc ile bir bellek bloğu ayırdığınızda, herhangi bir şeyle doldurulabilir, bu yüzden başlangıçta sıfır yazmanız gerekir.

bzero(r,e-s+1);

ayrıca indeks s değil de indeks 0'dan r'ye kopyalamaya başlamak istersiniz. Her ikisi için de s kullanmamalısınız.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
katma
bu, çıkartılacak bayt sayısının 1’ini kopyalayacaktır. (start == end ise, yine de bir bayt kopyalamanız gerekir. 'r []' içindeki her byte yazılacağından, onu başlatmanız gerekmez (hata ayıklamayı kolaylaştırmak dışında) ve malloc'ların bayt sayısı '\ 0' baytının izlenmesi için yer olması gerektiği için çok kısa
katma yazar user3629249, kaynak
düzeltildi, teşekkürler.
katma yazar Stewart Grant, kaynak

Bence problem burada olabilir:

r[s] = src[s];

Olarak değiştir

r[i++] = src[s];

i , r dizesinin dizinini izler ve 0 olarak başlatılır.

0
katma

Bence problem burada olabilir:

r[s] = src[s];

Olarak değiştir

r[i++] = src[s];

i , r dizesinin dizinini izler ve 0 olarak başlatılır.

0
katma

Bence problem burada olabilir:

r[s] = src[s];

Olarak değiştir

r[i++] = src[s];

i , r dizesinin dizinini izler ve 0 olarak başlatılır.

0
katma