Προς το περιεχόμενο

c strcpy().source code??


Προτεινόμενες αναρτήσεις

Δημοσ.

γεια σας,

το ξέρω ότι η συγκεκριμένη συνάρτηση υπάρχει απλά στην περίπτωση που δεν υπήρχε θα ήθελα να ήξερα να το γράφω μόνη μου το κώδικα  απλά κολλάω κάπου|

 

#include <stdio.h>
#include <stdlib.h>
char *my_strcpy(char *,char *);

 main() 
    { 
       char strA='k', strB='j' ;  
                  my_strcpy(*strB,*strA); 
        puts(strB); 
    }     

  char *my_strcpy(char *destination, char *source) 
   { 
       char *p = destination; 
       while (*source != '\0') 
       { 
           *p++ = *source++; 
       } 
       
       return destination; 
   } 
}
τι κάνω λάθος και δεν μου κάνει την δουλειά της strcpy;;;

 

 

Δημοσ.

Κάποια εμφανή είναι τα ακόλουθα:

 

Στην αρχή ορίζεις char strA = 'k' και, strB='j';

Απλά ορίζεις χαρακτήρες δηλαδή - χωρίς null terminator φυσικά αφού δεν είναι strings.

Αυτό είναι εντελώς διαφορετικό απο το char *strA = "k" ή το char *strA = {'k', '\0'} τα οποία ορίζουν strings και στη πρώτη περίπτωση ο null terminator μπαίνει απο τον compiler.

 

Μετά στο my_strcpy(*strB, *strA) θέλεις με βάση το function να περάσεις pointers - δηλαδή διευθύνσεις μνήμης...εσύ τί περνάς στο function για πρόσεξε; Βέβαια θέλεις να περάσεις strings και όχι chars...οπότε δεν θα είναι ακριβώς το ίδιο argument όταν θα περάσεις τα string ;).

 

 

Στο while loop γράφεις *p++ = *source++ , τι ακριβώς αυξάνεις κατα 1 εκεί ξέρεις; Τί έχει προτεραιότητα το * ή το ++ ;)

 

Το function σου γιατί επιστρέφει κάτι; Γιατί υποτίθεται ότι περάσαμε pointers στο function και όχι values;

 

Γενικώς έχεις πολλά θεμελιώδη λάθη οπότε δεν μπήκα καν στη λογική του προγράμματος. Διόρθωσε αυτά και βλέπουμε και τη λογική.

Δημοσ.

... 

τι κάνω λάθος και δεν μου κάνει την δουλειά της strcpy;;;

Η συνάρτησή σου είναι σωστή, αυτό που είναι λάθος ειναι ο ορισμός των strA και strB, καθώς και το πέρασμά τους στην συνάρτηση.

 

Όπως είπε και ο ZAKKWYLDE, τα ορίζεις ως χαρακτήρες αντί για strings. Ρίξε μια ματιά εδώ για το τί είναι, πως ορίζονται και πως περνιόνται ως ορίσματα τα strings.

 

EDIT:

 

Σου παραθέτω και μια πιο συνηθισμένη γραφή του κώδικα της συνάρτησης, που ουσιαστικά είναι ίδιος με τον δικό σου...

 

char *my_strcpy( char *dst, const char *src )
{
	char *to = dst;
	while ( (*to++ = *src++) )
		/* void */ ;

	return dst;
}

Δημοσ.

Βέβαια δεν υπάρχει λόγος να επιστρέφει κάτι η συνάρτηση, αφού υποτίθεται ότι θέλει ότι έχει το source να το γράψει στο destination. Σε αυτή τη περίπτωση δεν χρειάζεται και τον εξτρα pointer μέσα στη συνάρτηση.

Δημοσ.

Βέβαια δεν υπάρχει λόγος να επιστρέφει κάτι η συνάρτηση, αφού υποτίθεται ότι θέλει ότι έχει το source να το γράψει στο destination. Σε αυτή τη περίπτωση δεν χρειάζεται και τον εξτρα pointer μέσα στη συνάρτηση.

Υπάρχει λογος, πχ...

 

char *src = "hello world", dst[255+1] = {'\0'};

puts( my_strcpy(dst, src) );

Και η κανονική strcpy() επιστρέφει το dst. Το εξηγώ κι εδώ: http://x-karagiannis.gr/prg/c-notes/strings/return-value/

Δημοσ.

Παραπλήσια λογική με την παραπάνω, και πιο χρήσιμη, έχει η συνάρτηση stpcpy(dst, src) της GNU (), η οποία επιστρέφει έναν δείκτη στο τέλος του dst (δηλαδή στο NUL byte). Δεν υπάρχει διαθέσιμη στα Windows.

 

Παράδειγμα...

 

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXSIZ_S	(255+1)


/* ----------------------------------- */
char *stpcpy( char *dst, const char *src )
{
	while( (*dst++ = *src++) )
		/* void */ ;

	return --dst;
}

/* ----------------------------------- */
int main( void )
{
	char *src = "Hello world.", dst[MAXSIZ_S] = {'\0'};
	char *cp = dst;
	size_t lensrc = strlen(src);

	while ( (cp = stpcpy(cp, src)) - dst <= MAXSIZ_S - lensrc )
		/* void */ ;
	*cp = '\0';

	printf( "%s\n", dst);

	return 0;
}

 

 

Έξοδος:

 

 

Hello world.Hello world.Hello world.Hello world.Hello world.Hello world.Hello wo
rld.Hello world.Hello world.Hello world.Hello world.Hello world.Hello world.Hell
o world.Hello world.Hello world.Hello world.Hello world.Hello world.Hello world.
Hello world.

 

 

Την έχω συμπεριλάβει στην αναβάθμιση που κάνω στην LIBS (στο module Unix & Unix-like functions) με την επιπρόσθετη δυνατότητα πως κάνει sanity chceks για NULL και πως λειτουργεί και με overlapping src & dst (τα εντοπίζει μόνη της, οπότε αν χρειάζεται κάνει malloc() προσωρινό buffer για το src).

 

Αν ακολουθήσετε το παραπάνω link της τεκμηρίωσής της, περιέχει κι ένα πιο βατό παράδειγμα, ως εναλλακτική της strcat(). Στο τέλος της τεκμηρίωσης, εκεί που λέει σε ποια γραμμή ποιανού αρχείου βρίσκεται ο κώδικας, με κλικ στον αριθμό της γραμμής σας δείχνει τον κώδικα της συνάρτησης, και βασικά όλου του module s2unix.c (για όποιον ενδιαφέρεται τα δει δηλαδή).

Δημοσ.

 

γεια σας,

 

το ξέρω ότι η συγκεκριμένη συνάρτηση υπάρχει απλά στην περίπτωση που δεν υπήρχε θα ήθελα να ήξερα να το γράφω μόνη μου το κώδικα  απλά κολλάω κάπου|

 

#include <stdio.h>
#include <stdlib.h>
char *my_strcpy(char *,char *);

 main() 
    { 
       char strA='k', strB='j' ;  
                  my_strcpy(*strB,*strA); 
        puts(strB); 
    }     

  char *my_strcpy(char *destination, char *source) 
   { 
       char *p = destination; 
       while (*source != '\0') 
       { 
           *p++ = *source++; 
       } 
       
       return destination; 
   } 
}
τι κάνω λάθος και δεν μου κάνει την δουλειά της strcpy;;;

 

 

 

 

Εγω νομιζω οτι ξερει οτι μεσα στην συναρτηση θελει να περασει δεικτες αλλα μπερδευεται με τον συμβολισμο ενος δεικτη μεσα δηλωση της συναρτησης σαν παραμετρο και με τον συμβολισμο μεσα στην κληση της.

 

Καταρχην το * αναλογα που χρησιμοποιειται θα εχει και διαφορετικο νοημα. ΣΚεψου οτι μολις δηλωσεις εναν δεικτη (οπως ακριβως κανεις και μεσα στην λιστα παραμετρων της συναρτησης σου) το * λεει στον μεταγλωτιστη οτι προκειται να δηλωσουμε εναν δεικτη. Απαξ και τον δηλωσεις στην συνεχεια καθε εμφανιση του συμβολου * σαν τελεστη παραγει το περιεχομενο της διευθυνσης μνημης στην οποια εχεις βαλει τον δεικτη να δειχνει.

 

Επισης η puts εκτυπώνει ενα string αρχιζοντας απο την θεση που της υποδικενυει το ορισμα της και τελειωνει στον '\0'. Ο strB ειναι χαρακτηρας. Δεν ειναι string.

Δημοσ.

αφου ξεμπέρδεψα στο μυαλό μου κάποια βασικότατα πράγματα μπορώ να πω ότι μου βγήκε. ευχαριστώ πάρα πολύ για τις συμπληρωματικές επεξηγήσεις σας, κάθισα να το λύσω μόνη γιατί δεν θα υπήρχε αλλιώς νόημα  , ευχαριστώ πάντως !!! σε λίγο έρχεται ποστ με δομές   :P  :confused:  :wacko:

 

 

#include<stdio.h>
#include<stdlib.h>



char * mystrcpy(char *,char *); //dilosi sinartisis mystrcpy

int main() 

{

 char to[10]="katerina";
 char from[10]="HELLO";
     printf("PRIN tn synartisi mystrcpy EINAI\n to=%s kai  from=%s  \n\n",to,from);//prin
     mystrcpy(to,from); //kalesma 
     printf("META EINAI\n to=%s kai from=%s\n\n", to, from);//meta

      
 system("pause");
      }
char * mystrcpy(char *to1, char *from1) { //os orismata 2 deiktes se XARAKTIRA
  
  while (*from1 != '\0') //elegxos oso to PERIEXOMENO tou from1 na einai diaforo 
  *to1++=*from1++ ; // oso einai diaforo ana8esi timis tou periexomenou from1 sto        periexomeno tou to1
    return to1;            //epistrofi ts timis tou prwto orismatos diladi tou to1
 }
     
     
  
Δημοσ.

Η τιμή επιστροφής της συνάρτησής σου δεν πρέπει να είναι αυτή που ήθελες. Νομίζω ήθελες να επιστρέψεις έναν δείκτη στην αρχή του to1, αλλά τώρα επιστρέφεις έναν δείκτη μετά το το τέλος του (δηλαδή στο αμέσως επόμενο από το NUL byte του to1).

 

Για να μπορείς να επιστρέψεις την αρχή του to1 πρέπει πρώτα να την αποθηκεύσεις σε έναν τοπικό δείκτη πριν από το λουπ, και να τον επιστρέψεις μετά το λουπ.

Δημοσ.

Νομίζω ότι είναι χαζό και μπερδεύει. Ακόμα και στο debugging προκαλεί προβλήματα. Ποτε δεν ξέρεις σε πια θέση είσαι κάθε φορα και πρέπει να την υπολογίζεις.

Δημοσ.

Νομίζω ότι είναι χαζό και μπερδεύει. Ακόμα και στο debugging προκαλεί προβλήματα. Ποτε δεν ξέρεις σε πια θέση είσαι κάθε φορα και πρέπει να την υπολογίζεις.

Δεν διαφωνώ στο ότι δυσχεραίνει το debugging (εξαρτάται κι από τον debugger). Δεν διαφωνώ ούτε στο ότι μπερδεύει, αλλά μονάχα όσους δεν είναι εξοικειωμένοι με τη γλώσσα. Για τους έμπειρους είναι κάτι σαν 2η φύση (για αυτό και ο χαρακτηρισμός "idiom").

 

Εγκυκλοπαιδικά, οι ρίζες του προέρχονται από τις παλιές εποχές, όπου στους περισσότερους compilers ή/και πλατφόρμες η συγκεκριμένη γραφή παρήγαγε ταχύτερο κώδικα. Πλέον δεν ισχύει (αλλά όχι και "χαζό" ρε συ :P ).

Δημοσ.

 

αφου ξεμπέρδεψα στο μυαλό μου κάποια βασικότατα πράγματα μπορώ να πω ότι μου βγήκε. ευχαριστώ πάρα πολύ για τις συμπληρωματικές επεξηγήσεις σας, κάθισα να το λύσω μόνη γιατί δεν θα υπήρχε αλλιώς νόημα  , ευχαριστώ πάντως !!! σε λίγο έρχεται ποστ με δομές   :P  :confused:  :wacko:

 

 

#include<stdio.h>
#include<stdlib.h>



char * mystrcpy(char *,char *); //dilosi sinartisis mystrcpy

int main() 

{

 char to[10]="katerina";
 char from[10]="HELLO";
     printf("PRIN tn synartisi mystrcpy EINAI\n to=%s kai  from=%s  \n\n",to,from);//prin
     mystrcpy(to,from); //kalesma 
     printf("META EINAI\n to=%s kai from=%s\n\n", to, from);//meta

      
 system("pause");
      }
char * mystrcpy(char *to1, char *from1) { //os orismata 2 deiktes se XARAKTIRA
  
  while (*from1 != '\0') //elegxos oso to PERIEXOMENO tou from1 na einai diaforo 
  *to1++=*from1++ ; // oso einai diaforo ana8esi timis tou periexomenou from1 sto        periexomeno tou to1
    return to1;            //epistrofi ts timis tou prwto orismatos diladi tou to1
 }
     
     
  

 

Γιατι χρησιμοποιεις to1 και from1 ? Χρησιμοποιησε τα to και from απευθειας και μεσα στην συναρτηση.

Τα to και from μεσα στην συναρτηση σαν μεταβλειτες δεικτη αμφοτερα θα ειναι ΔΙΑΦΟΡΕΤΙΚΑ απο αυτα στην main

Σαν τοπικες μεταβλητες λοιπον με εμβελεια μεσα στο μπλοκ της συναρτησης σου πρεπει να ξαναδηλωθουν στην λιστα

παραμετρων ωστε να μπορουν να χρησιμοποιηθουν μετα μεσα στην συναρτηση.

 

Επισης οπως σου προτεινει και ο migf1 δηλωσε και αρχικοποιησε μια ακομη μεταβλητη δεικτη ονομασε την tmp πχ

η οποια θα δειχνει στην αρχη του to το οποιο τροποποιείται απο την αναθεση με το from. Γενικα τα to1 και from1 που χρησιμοποιεις τωρα ειναι ΑΝΤΙΓΡΑΦΑ. Δεν ειναι οι αυθεντικες μεταβλητες δεικτων απλα κανουν δουλεια επειδη κατα την κληση αρχικοποιούνται με αυτες. Φυσικα και τα to και from σκετα μεσα στην συνάρτηση και αυτα αντιγραφα θα ειναι απλα θα εχουν ιδιο ονομα.

 

Πρεπει να τα ξεκαθαρισεις αυτα αν θες να εισαι αποτελεσματικοτερη.

 

p.s Οταν ολοκληρώσεις οτι χρειάζεται αυτο που θα πρεπει να επιστρέφει η συνάρτηση ειναι ο tmp. Ο οποιος θα δειχνει στην αρχη του τροποποιημένου πλεον to ή to1 οπως το έχεις τωρα ;)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...