A “ karakterlánc ” a C

függvényt tartalmazza hogy létezik-e egy needle sztring egy másik sztringben haystack, és visszaadja-e a pozíciót, ha van, vagy 0, ha nem “, kivéve, ha a helyzet 0, ebben az esetben nem található.

A kód javításának módjait keresi, különösképpen a jobb hibakezelést.

#include <stdio.h> #include <stdlib.h> #include <string.h> size_t contains(const char * needle, const char *haystack); int main(void) { char *needle = "test"; char *haystack = "This is a dinosaurtest."; printf("Position: %lu", contains(needle, haystack)); return EXIT_SUCCESS; } size_t contains(const char * needle, const char *haystack) { if(needle == NULL || haystack == NULL) { return 0; } long int first_char_pos = -1; size_t len_h = strlen(haystack); size_t len_n = strlen(needle); size_t i, j; size_t exist_count = 0; // Find the first character. If it doesn"t exist, we"re done. for(i = 0; i < len_h; i++) { if((haystack[i] == needle[0]) && (first_char_pos == -1)) { first_char_pos = i; exist_count++; } } if(first_char_pos == -1) { return 0; } printf("First char match index: %li\n", first_char_pos); printf("Char: %c\n", haystack[first_char_pos]); size_t current_index = (size_t) first_char_pos; for(i = first_char_pos; i < len_h; i++) { if(haystack[i] == needle[exist_count] && (i == (current_index + 1))) { current_index = i; exist_count++; } printf("Exist count: %lu\n", exist_count); //<--Debugging if(exist_count == len_n) { return first_char_pos; } } return 0; } 

Megjegyzések

  • Kérjük, adjon hozzá néhány példát, hogy pontosan megmutassa, mire gondol, ha azt mondja, hogy ” tartalmaz “. Kétlem, hogy a kódod a rendeltetésszerűen működik.
  • Ez már létezik: strstr(). ‘ s egy strnstr() nevű biztonságosabb verzió. Itt találhat megvalósítást: github.com/lattera/freebsd/blob/master/lib/libc/string/…
  • @RolandIllig: miért, meg tudja magyarázni?
  • A contains("tt", "test") igaznak kell-e lennie?
  • @ CacahueteFrito Tehát a felhasználhatóság és teljesítményében nem elhanyagolható költségeket fizet az adatok sérülésének elfedése érdekében néhány ritka esetben, ahelyett, hogy a program invariánsaira hagyatkozna, javítaná az adatokat vagy jelentené a hibát? Ez rossz ötletnek tűnik.

Válasz

Csak néhány megjegyzés:

  • Az utolsó sor után adjon hozzá egy új sort:

     $ ./nh First char match index: 18 Char: t Exist count: 1 Exist count: 2 Exist count: 3 Exist count: 4 Position: 18 $ 
  • Nem tudom, mi a használt fordító, de a gcc és a -Wall -Wextra -pedantic fordítással a következőket kapja:

    gcc -O2 nh.c -lm -o nh -Wall -Wextra -pedantic nh.c: In function ‘contains’: nh.c:25:15: warning: unused variable ‘j’ [-Wunused-variable] size_t i, j; ^ 
  • A kód formázásának következetesebbnek kell lennie. Például ebben a sorban írjon egy szóközt a needle elé, de ne tegyen egy előtagot haystack:

    size_t contains(const char * needle, const char *haystack); 
  • %lu nem hordozható specifikáció a size_t típushoz, a C99-ben bevezetett %zu -t kell használnia.

  • Ön azt mondta:

visszaadja a pozíciót, ha igen, vagy 0, ha nem “t, hacsak a helyzet 0, ebben az esetben nem található.

Ez tényleg nem jó. Például ezzel 0-val tér vissza:

char *needle = "This"; char *haystack = "This is a dinosaurtest."; 

Ezzel a nullát is visszaadja:

char *needle = "non-existent"; char *haystack = "This is a dinosaurtest."; 

Ebben a két példában nem lehet különbséget tenni a siker és a kudarc között. Valójában a atoi() is ugyanaz a probléma. Nem tudom, milyen operációs rendszert használ de talán használhatja a ssize_t -t visszatérítési típusként, ha rendelkezésre áll, és hiba esetén -1-et ad vissza.

Válasz

Hozzáadás @Arkadiusz Drabczyk előző válaszához:

A contains egyszerű, triviális megvalósítása lehetséges így történt:

ssize_t contains(const char * needle, const char *haystack) { char *needle_in_haystack; if(!needle || !haystack) return -1; needle_in_haystack = strstr(haystack, needle); return needle_in_haystack ? needle_in_haystack - haystack : -1; } 

Ezután ennek a programnak (a fent említett néhány változtatással) működnie kell:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> ssize_t contains(const char * needle, const char *haystack) { char *needle_in_haystack; if(!needle || !haystack) return -1; needle_in_haystack = strstr(haystack, needle); return needle_in_haystack ? needle_in_haystack - haystack : -1; } int main(void) { char *needle = "test"; char *haystack = "This is a dinosaurtest."; char *haystack2 = "This does not contain the string."; printf("Position: %zd\n", contains(needle, haystack)); printf("Position: %zd\n", contains(needle, haystack2)); return EXIT_SUCCESS; } 

Kimenet:

Pozíció: 18
Pozíció: -1

Megjegyzések

  • Eltávolítom az ellenőrzést, hogy a bemenet nem NULL, és ju ehhez használjon nyelvi kiterjesztést (__attribute__((nonnull)) a GCC-ben). A NULL olyan dolog, amit soha nem várhatna inputként ehhez a függvényhez, és egy vagy két felesleges kódsort ad hozzá. Inkább a függvény dokumentációjába szeretnék írni: ” Ha ennek a függvénynek a bemenete NULL mutató, a viselkedés nincs meghatározva. “.
  • @CacahueteFrito Az eredeti kód megcsinálta, és szeretnék törekedni a kompatibilitásra (ki tudja, hogyan használta az OP?).
  • Hiányzik a ssize_t: #include <sys/types.h>. Egy másik lehetőség az ptrdiff_t használata lenne, a #include <stddef.h>; valójában mutató különbséget ad vissza: ? needle_in_haystack - haystack :

Válasz

A kódod nem működik. 0 értéket ad vissza a következőhöz: haystack "abbc" és needle "bc", bár a haystack tartalmaz needle .

Válasz

Nem kell az első ciklus és az összes hosszszámítás. Ha nem találja az első betűt, akkor a függvény nem fog sikerülni, de az első betűnek csak a második előfordulása illeszkedik a tűhöz.

A feladat néhány sorra csökkenthető:

int contains(char *buf, char *needle) { char *src, *srch, *srcp; for(src=buf; *src; src++) { for(srch = needle, srcp = src; *srch && *srcp && *srch == *srcp; srch++, srcp++); if(!*srch) return src - buf; } return -1; } 

Megjegyzések

  • Mi az a jó módszer, amellyel jobb lehet kompaktabb, hatékonyabb C-kódot írni, mint ez ?Ez a sorta K & R C-re emlékeztet.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük