Joops elikkä tässä kehittelin vb:n instr funktiota vastaavan funktion tai oikeastaan yritän kehitellä no tässä kuitenkin koodi
#include <stdio.h> #include <string.h> char *substr(char *tmp, int x, int y); int instr(char *teksti, char *merkki); int main(void) { //oli vaan et nään toimiiko printf("Alku\n"); char joo[1000]; int y; sprintf(joo,"Moicca jee"); //käytetään instr funktiota y = instr(joo,"a"); printf("%i\n",y); } int instr(char *teksti,char *merkki) { int t,a; //otetaan ylös tekstin pituus a = strlen(teksti); for(t=0; t>a; t++) { //verrataan merkkiin if (!strcmp(substr(teksti,t,1),merkki)) { return t; //jos löytyy niin palautetaan paikka break; } else { //jos ei niin palautetaan 0 return 0; } } } char *substr(char *tmp, int x, int y){ char *string = strdup(tmp); string[x + y - 1] = '\0'; return string + x - 1; }
Mutta tämä funktio palauttaa joka tapauksessa 134516398.
Mistä tämä johtuu?
Korjaus vielä
for(t=1;
t<a eikä t>a. Ja t=0 on oikeampi, koska voihan se olla alussa asti. return -1 tai muu virhearvo for-loopin jälkeen vielä. Mitään elseä ei myöskään tarvita. Substr ei tee uutta tekstiä, joten et voi nollamerkkiä siihen laittaa. Vertaile tekstejä etsittävän pituuden verran memcmp-funktiolla.
else-lohkon takia funktio palauttaa aina nollan, jos etsittävä merkki ei ole "teksti":n alussa. Myös huolimaton muistinkäsittely substr-funktiossa voi aiheuttaa ongelmia. Jos tosiaan etsii merkkiä, ei merkkijonoja tarvita. Etsinnän voi toteuttaa vaikka näin:
int instr(char *teksti, char merkki) { for(int i=0, teksti[i]!='\0'; i++) if(teksti[i]==merkki) return i; return -1; // ei löydy }
Tätä funktiota kutsuttaisiin: instr("asdlkdf", 'k'); Voi myös käyttää string.h:n valmista strcspn-funktiota.
Nyt siis os etsii vain yhtä merkkiä, kuten hänen kertomansa string.h:n funktiokin. Kokonainen tekstinpätkä oli tarkoitus löytää.
Jos kelpaa string.h:ta käyttävä funktio, niin homma menee helposti
int InStr(const char * const teksti, const char * const etsittava) { // Pointteri oikeaan kohtaan char * kohta = strstr(teksti, etsittava); // Jos löytyi, palautetaan kohdan ja alun osoitinten erotus. if (kohta != NULL) return (kohta - teksti); // Muuten palautetaan -1 return -1; }
Jos pitää itse tehdä, niin silloin tehdään kaikki ilman kirjastoja:
int InStr(const char * const teksti, const char * const etsittava) { int i, j, p1, p2; // Merkkijonojen pituudet for (p1 = 0; teksti[p1] != 0; ++p1); for (p2 = 0; etsittava[p2] != 0; ++p2); // Jos tekstissä ei olisi enää tilaa etsittävälle, sitä ei voi olla enää p1 = p1 - p2 + 1; // Joka kohdasta for (i = 0; i < p1; ++i) { // Koko etsittävä jono for (j = 0; j < p2; ++j) { // Onko eri merkki kuin pitäisi? if (teksti[i+j] != etsittava[j]) { break; // Ei siis tässä ainakaan } } // Jos päästiin loppuun, palautetaan tämä kohta if (j == p2) return i; } // Eipä löytynyt. return -1; }
Alkuperäisen koodisi virheellinen palautusarvo tulee siis siitä, että väärän ehdon takia silmukkaa ei suoriteta kertaakaan ja palautusarvo jää laittamatta. Kääntäjä sanoo kyllä, että joka tavalla ei tule arvoa palautettua. Ja tosiaan tuo else on virheellinen ajatus.
Aihe on jo aika vanha, joten et voi enää vastata siihen.