Waarom krijg ik vreemde personages die mijn deelreeks leiden?

Ik probeer een functie in C te maken die een substring van een gegeven char array retourneert. Het geeft me de meeste van de juiste uitvoer, maar ik krijg ook een aantal vreemde karakters aan het begin van de string. Als bijvoorbeeld de invoer "abcdefg" wordt gegeven en om tekens 3 tot 5 wordt gevraagd, krijg ik "ÀvWdef". Dus het lijkt erop dat ik de g goed afsnijd, maar het doet gewoon iets vreemds met de eerste 3 tekens in plaats van ze te negeren. Mijn code is hieronder opgenomen:

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
met betrekking tot deze regel: 'String r = (String) malloc ((e - s + 1) * sizeof (char));' 1) In C, werp de geretourneerde waarde niet van malloc (en familie van functies) 2) controleer altijd (! = NULL) de geretourneerde waarde voordat u deze gebruikt om te zorgen dat de bewerking is geslaagd. 3) sizeof (char) is altijd 1, dus mulitplying by 1 is verspilling van code. stel voor de '* sizeof (char)' te verwijderen
toegevoegd de auteur user3629249, de bron
als start == einde, dan is de malloc natuurlijk 1 karakter te kort. dit is van toepassing ongeacht de afstand tussen begin en einde. Wanneer de 's' voor het laatst is opgehoogd en vervolgens de toewijzing van '\ 0' aan de huidige plaats waar 's' wijst, is dat voorbij het einde van de toegewezen buffer. Dit resulteert in ongedefinieerd gedrag en kan/zal leiden tot een seg-foutgebeurtenis
toegevoegd de auteur user3629249, de bron
met 's' als de offset naar 'r []' betekent dat de gekopieerde gegevens voorbij het einde van de array 'r []' zullen schrijven, tenzij 'start = 0'
toegevoegd de auteur user3629249, de bron
met 's' als de offset naar 'r []' betekent dat de gekopieerde gegevens voorbij het einde van de array 'r []' zullen schrijven, tenzij 'start = 0'
toegevoegd de auteur user3629249, de bron

9 antwoord

U hebt een logische fout in:

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

De index voor src is correct. Maar de index voor r is dat niet. U hebt een andere index nodig.

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

Na de lus, in plaats van:

r[s] = '\0';

gebruik:

r[i] = '\0';

U hebt ook een logische fout in het aantal tekens dat moet worden toegewezen met malloc .

Gegeven s = 3 en e = 5 , geeft u een string terug die bestaat uit src [3] , src [4] , src [5] . Dat zijn 3 karakters. Als u het afsluitende nul-teken toevoegt, hebt u 4 tekens nodig. (e - s + 1) geeft u alleen 3 . Gebruik in plaats daarvan (e - s + 2) .

2
toegevoegd
Naast de fout die 'R Sahu' heeft aangegeven, is het zo dat als je van plan bent om je start en end een/inclusief/bereik te geven, je malloc toewijst voor één karakter/minder/dan wat vereist is. Als alternatief, als je van plan bent om een ​​semi-open bereik te hebben (wat de 'standaard' manier is), dan zou je while-lusconditie moeten gaan naar while (s , d.w.z., strikte ongelijkheid.
toegevoegd de auteur Happy Green Kid Naps, de bron

U hebt een logische fout in:

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

De index voor src is correct. Maar de index voor r is dat niet. U hebt een andere index nodig.

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

Na de lus, in plaats van:

r[s] = '\0';

gebruik:

r[i] = '\0';

U hebt ook een logische fout in het aantal tekens dat moet worden toegewezen met malloc .

Gegeven s = 3 en e = 5 , geeft u een string terug die bestaat uit src [3] , src [4] , src [5] . Dat zijn 3 karakters. Als u het afsluitende nul-teken toevoegt, hebt u 4 tekens nodig. (e - s + 1) geeft u alleen 3 . Gebruik in plaats daarvan (e - s + 2) .

2
toegevoegd
Naast de fout die 'R Sahu' heeft aangegeven, is het zo dat als je van plan bent om je start en end een/inclusief/bereik te geven, je malloc toewijst voor één karakter/minder/dan wat vereist is. Als alternatief, als je van plan bent om een ​​semi-open bereik te hebben (wat de 'standaard' manier is), dan zou je while-lusconditie moeten gaan naar while (s , d.w.z., strikte ongelijkheid.
toegevoegd de auteur Happy Green Kid Naps, de bron

U hebt een logische fout in:

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

De index voor src is correct. Maar de index voor r is dat niet. U hebt een andere index nodig.

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

Na de lus, in plaats van:

r[s] = '\0';

gebruik:

r[i] = '\0';

U hebt ook een logische fout in het aantal tekens dat moet worden toegewezen met malloc .

Gegeven s = 3 en e = 5 , geeft u een string terug die bestaat uit src [3] , src [4] , src [5] . Dat zijn 3 karakters. Als u het afsluitende nul-teken toevoegt, hebt u 4 tekens nodig. (e - s + 1) geeft u alleen 3 . Gebruik in plaats daarvan (e - s + 2) .

2
toegevoegd
Naast de fout die 'R Sahu' heeft aangegeven, is het zo dat als je van plan bent om je start en end een/inclusief/bereik te geven, je malloc toewijst voor één karakter/minder/dan wat vereist is. Als alternatief, als je van plan bent om een ​​semi-open bereik te hebben (wat de 'standaard' manier is), dan zou je while-lusconditie moeten gaan naar while (s , d.w.z., strikte ongelijkheid.
toegevoegd de auteur Happy Green Kid Naps, de bron

Wanneer u een blok geheugen toewijst met malloc, kan het met alles worden gevuld, dus u moet er aanvankelijk nul aan schrijven.

bzero(r,e-s+1);

verder wil je beginnen met kopiëren naar r van index 0 niet indexen. Je zou s niet voor beide moeten gebruiken.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
toegevoegd
dit zal 1 kopie kopiëren van het aantal te extraheren bytes. (als start == einde moet dan nog steeds één byte worden gekopieerd. Aangezien elke byte in 'r []' zal worden geschreven, hoeft het niet te worden geïnitialiseerd (behalve om het debuggen gemakkelijker te maken) en het aantal gemiste bytes is te kort omdat er ruimte moet zijn voor de achterliggende '\ 0' byte
toegevoegd de auteur user3629249, de bron
gecorrigeerd, bedankt.
toegevoegd de auteur Stewart Grant, de bron

Wanneer u een blok geheugen toewijst met malloc, kan het met alles worden gevuld, dus u moet er aanvankelijk nul aan schrijven.

bzero(r,e-s+1);

verder wil je beginnen met kopiëren naar r van index 0 niet indexen. Je zou s niet voor beide moeten gebruiken.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
toegevoegd
dit zal 1 kopie kopiëren van het aantal te extraheren bytes. (als start == einde moet dan nog steeds één byte worden gekopieerd. Aangezien elke byte in 'r []' zal worden geschreven, hoeft het niet te worden geïnitialiseerd (behalve om het debuggen gemakkelijker te maken) en het aantal gemiste bytes is te kort omdat er ruimte moet zijn voor de achterliggende '\ 0' byte
toegevoegd de auteur user3629249, de bron
gecorrigeerd, bedankt.
toegevoegd de auteur Stewart Grant, de bron

Wanneer u een blok geheugen toewijst met malloc, kan het met alles worden gevuld, dus u moet er aanvankelijk nul aan schrijven.

bzero(r,e-s+1);

verder wil je beginnen met kopiëren naar r van index 0 niet indexen. Je zou s niet voor beide moeten gebruiken.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
toegevoegd
dit zal 1 kopie kopiëren van het aantal te extraheren bytes. (als start == einde moet dan nog steeds één byte worden gekopieerd. Aangezien elke byte in 'r []' zal worden geschreven, hoeft het niet te worden geïnitialiseerd (behalve om het debuggen gemakkelijker te maken) en het aantal gemiste bytes is te kort omdat er ruimte moet zijn voor de achterliggende '\ 0' byte
toegevoegd de auteur user3629249, de bron
gecorrigeerd, bedankt.
toegevoegd de auteur Stewart Grant, de bron

Ik denk dat het probleem hier is:

r[s] = src[s];

Verander het in

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

waarbij i index van tekenreeks r bijhoudt en wordt geïnitialiseerd naar 0 .

0
toegevoegd

Ik denk dat het probleem hier is:

r[s] = src[s];

Verander het in

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

waarbij i index van tekenreeks r bijhoudt en wordt geïnitialiseerd naar 0 .

0
toegevoegd

Ik denk dat het probleem hier is:

r[s] = src[s];

Verander het in

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

waarbij i index van tekenreeks r bijhoudt en wordt geïnitialiseerd naar 0 .

0
toegevoegd