Чаму я атрымліваю дзіўныя сімвалы, якія вядуць сваю падрадок?

Я спрабую стварыць функцыю ў C, якая вяртае падрадок любога зададзенага масіва знакаў. Гэта дае мне вялікую частку правільнага вываду, але я таксама атрымліваю некаторыя дзіўныя сімвалы ў пачатку радка. Напрыклад, калі дадзены ўваходных «ABCDEFG» і папрасіў Гольц 3 да 5, ён дае мне «ÀvWdef». Так з'яўляецца я набіраюся г адрэзаць правільна, але гэта проста робіць нешта дзіўнае ў першых 3 знакаў замест таго, каб ігнараваць іх. Мой код прыведзены ніжэй:

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
адносна гэтага радка: 'Радок г = (String) Таноса ((е - е + 1) * SizeOf (Char));' 1) У C, ня адкідаюць вяртаецца значэнне з Таноса (і сямейства функцый) 2) заўсёды правяраць (! = NULL) вяртаецца значэнне, перш чым выкарыстоўваць яго для забеспячэння паспяховага выканання аперацыі. 3) SizeOf (Char) заўсёды роўны 1, так што mulitplying на 1 марнаванне коды. прапанаваць зняцця '* SizeOf (Char)'
дададзена аўтар user3629249, крыніца
калі пачаць == канца, то, відавочна, Таноса 1 персанаж занадта кароткі. гэта ставіцца Незалежна ад адлегласці паміж пачаткам і канцом. Калі «s» з'яўляецца апошнім павялічваецца, а затым прысваенне «\ 0» у бягучым месцы, дзе «s» кропак, гэта значыць у канцы мінулага вылучанага буфера. Гэта прыводзіць да непрадказальных паводзінаў і можа/будзе прыводзіць да падзеі няспраўнасці сегментнай
дададзена аўтар user3629249, крыніца
выкарыстоўваючы «S» як зрух «г []» азначае, што скапіяваныя дадзеныя будуць пісаць міма канца «г []» масіў, калі «не пачне = 0»
дададзена аўтар user3629249, крыніца
выкарыстоўваючы «S» як зрух «г []» азначае, што скапіяваныя дадзеныя будуць пісаць міма канца «г []» масіў, калі «не пачне = 0»
дададзена аўтар user3629249, крыніца

9 адказы

У вас ёсць лагічная памылка ў:

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

Індэкс для ЦСІ правільна. Але індэкс г няма. Вам трэба яшчэ адзін індэкс.

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

Пасля таго, як завесы, замест таго, каб:

r[s] = '\0';

выкарыстоўваць:

r[i] = '\0';

У вас таксама ёсць лагічная памылка ў колькасці сімвалаў вылучыць з дапамогай Таноса .

Улічваючы s = 3 і е = 5 , вы вяртаеце радок, якая складаецца з Src [3] , ЦСІ [4] , SRC [5] . Гэта 3-х знакаў. Пры даданні завяршальнага нулявога сімвала, неабходна 4-х знакаў. <�Код> (е - s + 1) дае толькі 3 . Выкарыстоўвайце (е - s + 2) замест гэтага.

2
дададзена
У дадатак да памылкі, што «R Sahu» паказаў, калі вы збіраецеся ў ваш пачаць і Перапыніць , каб быць/ўключна/дыяпазон, то ваш Таноса вылучае для адзін знак/менш /, чым патрабуецца. З іншага боку, калі вы збіраецеся яго быць напаўадкрытага дыяпазон (які з'яўляецца «стандартным» спосабам), то ваш стан у той час як цыкл павінен ісці While (s <�е) гэта значыць, строгае няроўнасць.
дададзена аўтар Happy Green Kid Naps, крыніца

У вас ёсць лагічная памылка ў:

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

Індэкс для ЦСІ правільна. Але індэкс г няма. Вам трэба яшчэ адзін індэкс.

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

Пасля таго, як завесы, замест таго, каб:

r[s] = '\0';

выкарыстоўваць:

r[i] = '\0';

У вас таксама ёсць лагічная памылка ў колькасці сімвалаў вылучыць з дапамогай Таноса .

Улічваючы s = 3 і е = 5 , вы вяртаеце радок, якая складаецца з Src [3] , ЦСІ [4] , SRC [5] . Гэта 3-х знакаў. Пры даданні завяршальнага нулявога сімвала, неабходна 4-х знакаў. <�Код> (е - s + 1) дае толькі 3 . Выкарыстоўвайце (е - s + 2) замест гэтага.

2
дададзена
У дадатак да памылкі, што «R Sahu» паказаў, калі вы збіраецеся ў ваш пачаць і Перапыніць , каб быць/ўключна/дыяпазон, то ваш Таноса вылучае для адзін знак/менш /, чым патрабуецца. З іншага боку, калі вы збіраецеся яго быць напаўадкрытага дыяпазон (які з'яўляецца «стандартным» спосабам), то ваш стан у той час як цыкл павінен ісці While (s <�е) гэта значыць, строгае няроўнасць.
дададзена аўтар Happy Green Kid Naps, крыніца

У вас ёсць лагічная памылка ў:

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

Індэкс для ЦСІ правільна. Але індэкс г няма. Вам трэба яшчэ адзін індэкс.

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

Пасля таго, як завесы, замест таго, каб:

r[s] = '\0';

выкарыстоўваць:

r[i] = '\0';

У вас таксама ёсць лагічная памылка ў колькасці сімвалаў вылучыць з дапамогай Таноса .

Улічваючы s = 3 і е = 5 , вы вяртаеце радок, якая складаецца з Src [3] , ЦСІ [4] , SRC [5] . Гэта 3-х знакаў. Пры даданні завяршальнага нулявога сімвала, неабходна 4-х знакаў. <�Код> (е - s + 1) дае толькі 3 . Выкарыстоўвайце (е - s + 2) замест гэтага.

2
дададзена
У дадатак да памылкі, што «R Sahu» паказаў, калі вы збіраецеся ў ваш пачаць і Перапыніць , каб быць/ўключна/дыяпазон, то ваш Таноса вылучае для адзін знак/менш /, чым патрабуецца. З іншага боку, калі вы збіраецеся яго быць напаўадкрытага дыяпазон (які з'яўляецца «стандартным» спосабам), то ваш стан у той час як цыкл павінен ісці While (s <�е) гэта значыць, строгае няроўнасць.
дададзена аўтар Happy Green Kid Naps, крыніца

Пры вылучэнні блока памяці з Таноса ён можа быць запоўнены ні з чым, так што вы павінны напісаць ад нуля да яго першапачаткова.

bzero(r,e-s+1);

Акрамя таго, вы хочаце, каб пачаць капіраванне на г з індэкса 0, а не індэкс с. Вы не павінны выкарыстоўваць з для абодвух.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
дададзена
гэта скапіюе 1 кароткі з ліку байтаў, якія будуць вынятыя. (Калі пачаць == канец тады яшчэ трэба скапіяваць адзін байт. Так як кожны байт у 'г [] будзе запісана, няма неабходнасці ініцыялізаваць яго (за выключэннем зрабіць адладку прасцей) і malloc'd лік байтаў занадта кароткім, там павінна быць месца для завяршальнага «\ 0» байт
дададзена аўтар user3629249, крыніца
выправіў, дзякуй.
дададзена аўтар Stewart Grant, крыніца

Пры вылучэнні блока памяці з Таноса ён можа быць запоўнены ні з чым, так што вы павінны напісаць ад нуля да яго першапачаткова.

bzero(r,e-s+1);

Акрамя таго, вы хочаце, каб пачаць капіраванне на г з індэкса 0, а не індэкс с. Вы не павінны выкарыстоўваць з для абодвух.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
дададзена
гэта скапіюе 1 кароткі з ліку байтаў, якія будуць вынятыя. (Калі пачаць == канец тады яшчэ трэба скапіяваць адзін байт. Так як кожны байт у 'г [] будзе запісана, няма неабходнасці ініцыялізаваць яго (за выключэннем зрабіць адладку прасцей) і malloc'd лік байтаў занадта кароткім, там павінна быць месца для завяршальнага «\ 0» байт
дададзена аўтар user3629249, крыніца
выправіў, дзякуй.
дададзена аўтар Stewart Grant, крыніца

Пры вылучэнні блока памяці з Таноса ён можа быць запоўнены ні з чым, так што вы павінны напісаць ад нуля да яго першапачаткова.

bzero(r,e-s+1);

Акрамя таго, вы хочаце, каб пачаць капіраванне на г з індэкса 0, а не індэкс с. Вы не павінны выкарыстоўваць з для абодвух.

Edit corrected < to <=

for(i =0; i <= e-s;i++)
    r[i] = src[s + i];
r[i] = '\0';
1
дададзена
гэта скапіюе 1 кароткі з ліку байтаў, якія будуць вынятыя. (Калі пачаць == канец тады яшчэ трэба скапіяваць адзін байт. Так як кожны байт у 'г [] будзе запісана, няма неабходнасці ініцыялізаваць яго (за выключэннем зрабіць адладку прасцей) і malloc'd лік байтаў занадта кароткім, там павінна быць месца для завяршальнага «\ 0» байт
дададзена аўтар user3629249, крыніца
выправіў, дзякуй.
дададзена аўтар Stewart Grant, крыніца

Я думаю, што праблема можа быць тут:

r[s] = src[s];

Зменіце яго на

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

дзе я адсочвае індэкс радкі г і ініцыялізуецца 0 .

0
дададзена

Я думаю, што праблема можа быць тут:

r[s] = src[s];

Зменіце яго на

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

дзе я адсочвае індэкс радкі г і ініцыялізуецца 0 .

0
дададзена

Я думаю, што праблема можа быць тут:

r[s] = src[s];

Зменіце яго на

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

дзе я адсочвае індэкс радкі г і ініцыялізуецца 0 .

0
дададзена