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

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

Δημοσ.

Να σημειώσω κι εγώ πως έχει λάθος το σνίπετ που πόσταρα παραπάνω... εκ παραδρομής έχω γράψει '\n' αντί για το σωστό '\0' στη συνθήκη του loop.

 

(έχω επίσης διπλο-τριπλο-ελέγχους οι οποίοι στη συγκεκριμένη ερώτηση δε χρειάζονται... αλλά μπορεί να αποδειχτούν χρήσιμοι αν ο κώδικας γίνει συνάρτηση κάποια στιγμή)

 

Έχεις ξεχάσει και το i μέσα στη δήλωσή του στη for :P

Κι επίσης θα μπορούσε να γραφεί και σαν:

for ( int i = 0; i < 51 && ( name1[i] = name[i] ); i++ );

Φαντάζομαι εκ παραδρομής έβαλες i < 50 έτσι δεν είναι;

 

EDIT:

Άσε το κατάλαβα, το ελέγχεις μέχρι εκεί ώστε να βάλεις μετά '\0' στο τελευταίο στοιχείο του πίνακα άν σταματήσει λόγω της συνθήκης του i...

  • Like 1
Δημοσ.

Ναι, γενικώς είναι για πέταμα αυτό που έχω γράψει (αποτέλεσμα βιασύνης και κούρασης).

 

EDIT (στο edit σου): Το είχα μέχρι 50 γιατί νόμιζα πως διάβαζα απευθείας από stdin, οπότε ήθελα να κόψω το '\n'... γενικώς άλλα αντί άλλων!

Δημοσ.

 

Σε αυτή τη περίπτωση η συμπεριφορά αυτή οφείλεται στο γεγονός ότι αυξάνεις το i πριν κάνεις την ανάθεση.

Με την γραμμή,

name2[i++] = name[i];

γίνονται οι εξής κινήσεις με αυτή τη σειρά: Αύξηση κατά 1 του i και φόρτωση του name[i_new] στο name2[i_new].

Έτσι αν name = "john", τότε στην πρώτη επανάληψη name2[1] = name[1] = 'j'.

Αυτό το πρόβλημα λύνεται με τον τρόπο που έκανες στο δέυτερο πρόγραμμα. Με την αλλαγή του i μετά την ανάθεση.

 

Τώρα το γεγονός ότι στο πρώτο πρόγραμμα μετά τη δουλειά που έκανες, το νέο string δεν ακολουθούνταν από "σκουπίδια" είναι κάτι το τυχαίο. Τα strings στη C είναι NULL terminated, πράγμα που σημαίνει ότι στο τέλος της χρήσιμης πληροφορίας μπαίνει ένας χαρακτήρας '\0'. Μετά από αυτόν ακολουθούν "σκουπίδια". Γι' αυτό και στην επανάληψη ψάχνεις τους χαρακτήρες του string μέχρι να συναντήσεις '\0'. Στην περίπτωσή μας τώρα εσύ θέλεις να τερματίσεις την επανάληψη μόλις διαβάσεις τον NULL character. Στο σημείο όμως στο οποίο κάνεις αύξηση του i, στο name2 αντιγράφεται στο τέλος και ο χαρακτήρας NULL από το name. Στην ουσία κοιτάς ένα σημείο μπροστά.

 

Στο δεύτερο κώδικά σου κάτι τέτοιο δε συμβαίνει. Οπότε εύκολα καταλαβαίνεις πως η επανάληψη τερματίζεται πριν αντιγράψεις και το NULL στο name2. Μετά όταν κάνεις την εκτύπωση του name2, εκτυπώνεται το string μέχρι να βρεθεί NULL, το οποίο βρίσκεται στο 51ο χαρακτήρα. Άρα διαβάζονται και όλα τα σκουπίδια, μέχρι εκείνο το σημείο.

 

Υπάρχουν δύο λύσεις:

  • αρχικοποιείς τα strings σου με NULL, όπως σου έδειξε ο migf1, είτε
  •  
  • όταν εξέλθεις της επανάληψης θέτεις name2 = '\0'.
  •  

Για το τελευταίο πρέπει να έχεις το νου σου συνέχεια, οπότε προτίμησε το πρώτο για να έχεις το κεφάλι σου ήσυχο.

 

Καταρχήν στη C δεν υπάρχει δήλωση main() έτσι όπως την έχεις. Για το θέμα με τα ονόματα, δοκίμασε...

Για εξησησε το μου καλυτερα.

int main( void )
{
    char name[51]  = {'\0'};
    char name2[51] = {'\0'};

    printf("Please enter your name: ");
    scanf("%50s", name);

    for (int =0; i < 50 && name[i] != '\n'; i++) {
        name2[i]  = name[i];
    }

    puts(name);
    puts(name2);

    return 0;
}
EDIT: http://www.insomnia.gr/topic/513504-%CE%B1%CE%BA%CE%B1%CF%84%CE%B1%CE%BD%CF%8C%CE%B7%CF%84%CE%B7-%CF%83%CF%85%CE%BC%CF%80%CE%B5%CF%81%CE%B9%CF%86%CE%BF%CF%81%CE%AC-c/?do=findComment&comment=52952130

 

 

 

Σωστά! Ο compiler παραπονιέται για το postfix increment του i στο name2[i++]:

warning: operation on ‘i’ may be undefined [-Wsequence-point]

οπότε τα αποτελέσματα δεν είναι αυτά που θέλουμε.

 

 

Γιατί αυξάνεται κατά ένα και μετά έχουμε παντού τον i_new ? Τον postfix τελεστή χρησιμοποίησε όχι τον prefix. Επίσης τον έχει στην αριστερή πλευρά της ανάθεσης οπότε μια λογική ερμηνεία της λειτουργίας θα ήταν ότι διαβάζεται το περιεχόμενο της μνήμης name, έπειτα αυτό τοποθετείται στην διεύθυνση name2 και μετά λόγω postfix αυξάνεται το i, δηλαδή αυτό που ήθελε ο OP.

 

Το λογικό όμως δεν ισχύει εδώ γιατί πέφτουμε σε αόριστη συμπεριφορά και μπορεί το αποτέλεσμα να είναι ό,τι θέλει ο compiler. Ίσως να μη το θυμάμαι καλά αλλά νομίζω δεν μπορείς να αλλάζεις την μεταβλητή στις δύο πλευρές της ανάθεσης (παρόμοιο δηλαδή με το i = i++ + i++)

λυθηκε με την υποδειξη του migf1, με τη αρχικοποιηση των πινακων με τον χαρακτηρα \0

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

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

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

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

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

Σύνδεση

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

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