giampoul Δημοσ. 29 Νοεμβρίου 2011 Δημοσ. 29 Νοεμβρίου 2011 Γειά σας παιδιά. Στον κώδικα: > . . const char *argv[]={"./xxx.x","7",NULL}; execvp("./xxx.x",argv); . . Αν θέλω στο πρόγραμμα xxx.x να δώσω 1ο όρισμα μια μεταβλητή int πως θα το κάνω;; Δηλαδή αν αντί για "7" θέλω να έχω μία int x ...;;
migf1 Δημοσ. 29 Νοεμβρίου 2011 Δημοσ. 29 Νοεμβρίου 2011 Εφόσον η execvp() περιμένει c-strings από το 2ο όρισμα και μετά, δεν μπορείς να της περάσεις int. Είναι σαν να έχεις φτιάξει μια συνάρτηση που περιμένει ως όρισμα ένα c-string κι εσύ να της περνάς int. Μπορείς όμως να φτιάξεις μια συνάρτηση που κάνει το ανάποδο από την atoi() ... π.χ. itoa() ... ή να χρησιμοποιήσεις την sprintf() για να μετατρέψεις μια int μεταβλητή σε c-string πριν την περάσεις στην execvp(). Επίσης για να είναι συμβατός ο κώδικάς σου σε όλους τους C compilers σε όλες τις πλατφόρμες, καλό είναι το NULL που περνάς ως τελευταίο όρισμα στην execvp() να το κάνεις cast σε (char *) μιας και πρόκειται για variadic συνάρτηση. Αν και η execvp() δεν είναι στάνταρ συνάρτηση της C. Δηλαδή... >execvp( "./xxx.x", itoa(7), (char *) NULL );
giampoul Δημοσ. 29 Νοεμβρίου 2011 Μέλος Δημοσ. 29 Νοεμβρίου 2011 Εφόσον η execvp() περιμένει c-strings από το 2ο όρισμα και μετά, δεν μπορείς να της περάσεις int. Είναι σαν να έχεις φτιάξει μια συνάρτηση που περιμένει ως όρισμα ένα c-string κι εσύ να της περνάς int. Μπορείς όμως να φτιάξεις μια συνάρτηση που κάνει το ανάποδο από την atoi() ... π.χ. itoa() ... ή να χρησιμοποιήσεις την sprintf() για να μετατρέψεις μια int μεταβλητή σε c-string πριν την περάσεις στην execvp(). Επίσης για να είναι συμβατός ο κώδικάς σου σε όλους τους C compilers σε όλες τις πλατφόρμες, καλό είναι το NULL που περνάς ως τελευταίο όρισμα στην execvp() να το κάνεις cast σε (char *) μιας και πρόκειται για variadic συνάρτηση. Αν και η execvp() δεν είναι στάνταρ συνάρτηση της C. Δηλαδή... >execvp( "./xxx.x", itoa(7), (char *) NULL ); Αν κατάλαβα σωστά, προσπάθησα αυτό: > execvp( "./xxx.x", itoa(x), (char *) NULL ); και μετά στο πρόγραμμα xxx.x αυτό: > ... y=atoi(argv[1]); Αλλά βγάζει σφάλμα στην execvp.Το θέμα είναι πως πρέπει να βάλω μια μεταβλητή στο argv[1] της execvp την οποία το πρόγραμμα την διαβάζει προηγουμένως από ένα αρχείο, οπότε δεν ξέρω την τιμή της.Καμία ιδέα;;;
migf1 Δημοσ. 29 Νοεμβρίου 2011 Δημοσ. 29 Νοεμβρίου 2011 Η atoi() δεν σου είναι χρήσιμη, μια itoa() θέλεις, αλλά αυτή δεν είναι στάνταρτ συνάρτηση της γλώσσας. Ή πρέπει να τη φτιάξεις μόνος σου ή να τη βρεις έτοιμη. Εναλλακτικά όπως σου έγραψα μπορείς να χρησιμοποιήσεις την στάνταρ συνάρτηση sprintf() για να μετατρέψεις την int μεταβλητή σου σε c-string, ώστε να περάσεις κατόπιν αυτό το c-string στην execvp. > int fromfile; char str[100+1] = {'\0'}; ... sprintf( str, "%d", fromfile ); execvp( "./xxx.x", str, (char *) NULL); ...
giampoul Δημοσ. 30 Νοεμβρίου 2011 Μέλος Δημοσ. 30 Νοεμβρίου 2011 Αυτό δούλεψε μια χαρά.Ευχαριστώ! Χρησιμοποίησα και την atoi() μετά στο πρόγραμμα xxx.x για να κάνω int και πάλι την μεταβλητή. Κάτι τελευταίο σχετικά με το typecast.. Μου εμφανίζει warning : x.c: In function ‘main’: x.c:28:9: warning: assignment makes integer from pointer without a cast [enabled by default] Για το εξης κομμάτι του κώδικα : > int A[l][m]; A[l][m]=(int *)shmat(segment_id,NULL,0); To πρόγραμμα λειτουργεί σχεδόν κανονικά και έχω δοκιμάσει κάποιες παραλλαγές για να φύγουν τα warning αλλά τίποτα. Μήπως γνωρίζεις ;
defacer Δημοσ. 30 Νοεμβρίου 2011 Δημοσ. 30 Νοεμβρίου 2011 Αυτό δούλεψε μια χαρά.Ευχαριστώ! Χρησιμοποίησα και την atoi() μετά στο πρόγραμμα xxx.x για να κάνω int και πάλι την μεταβλητή. Κάτι τελευταίο σχετικά με το typecast.. Μου εμφανίζει warning : x.c: In function ‘main’: x.c:28:9: warning: assignment makes integer from pointer without a cast [enabled by default] Για το εξης κομμάτι του κώδικα : > int A[l][m]; A[l][m]=(int *)shmat(segment_id,NULL,0); To πρόγραμμα λειτουργεί σχεδόν κανονικά και έχω δοκιμάσει κάποιες παραλλαγές για να φύγουν τα warning αλλά τίποτα. Μήπως γνωρίζεις ; Έχεις κάνει ένα πίνακα A από int, και μέσα σ' αυτόν πας και αποθηκεύεις int*. Εξ ου και το warning. Αυτό είναι πολύ σοβαρό λάθος και το πρόγραμμά σου δουλεύει "κατά τύχη". Σαν types, το int και το int* δεν έχουν καμία απολύτως σχέση. Φαντάσου να είχες πίνακα από char και να αποθήκευες μέσα int*, θεωρητικά είναι ακριβώς το ίδιο λάθος. Τώρα στην πράξη, το πρόγραμμά σου δουλεύει όπως λες γιατί κατά τύχη sizeof(int) == sizeof(int*) με τον συγκεκριμένο compiler που χρησιμοποιείς (για να είμαι δίκαιος, και με την πλειοψηφία ίσως των compilers σήμερα). Αλλά αυτό έτυχε και συμβαίνει, δεν είναι σε καμία περίπτωση εγγυημένο. Δεν μπορώ να σου πώ τι θα έπρεπε να κάνεις γιατί δεν ξέρω τι είναι αυτός ο πίνακας A και τι κάνεις μαζί του, αλλά δυο βασικά πράγματα: 1. Γιατί δεν τον ορίζεις σαν void* πίνακα αφού αυτό πας και βάζεις μέσα (προκύπτει από το signature της shmat)? 2. Όσο casting και να κάνεις το πολύ πολύ να αναγκάσεις τον compiler να σκάσει. Το πρόβλημα που εξήγησα θα συνεχίσει να παραμένει.
giampoul Δημοσ. 30 Νοεμβρίου 2011 Μέλος Δημοσ. 30 Νοεμβρίου 2011 Έχεις κάνει ένα πίνακα A από int, και μέσα σ' αυτόν πας και αποθηκεύεις int*. Εξ ου και το warning. Αυτό είναι πολύ σοβαρό λάθος και το πρόγραμμά σου δουλεύει "κατά τύχη". Σαν types, το int και το int* δεν έχουν καμία απολύτως σχέση. Φαντάσου να είχες πίνακα από char και να αποθήκευες μέσα int*, θεωρητικά είναι ακριβώς το ίδιο λάθος. Τώρα στην πράξη, το πρόγραμμά σου δουλεύει όπως λες γιατί κατά τύχη sizeof(int) == sizeof(int*) με τον συγκεκριμένο compiler που χρησιμοποιείς (για να είμαι δίκαιος, και με την πλειοψηφία ίσως των compilers σήμερα). Αλλά αυτό έτυχε και συμβαίνει, δεν είναι σε καμία περίπτωση εγγυημένο. Δεν μπορώ να σου πώ τι θα έπρεπε να κάνεις γιατί δεν ξέρω τι είναι αυτός ο πίνακας A και τι κάνεις μαζί του, αλλά δυο βασικά πράγματα: 1. Γιατί δεν τον ορίζεις σαν void* πίνακα αφού αυτό πας και βάζεις μέσα (προκύπτει από το signature της shmat)? 2. Όσο casting και να κάνεις το πολύ πολύ να αναγκάσεις τον compiler να σκάσει. Το πρόβλημα που εξήγησα θα συνεχίσει να παραμένει. Εχω επίσης και έναν Β πίνακα: > int B[M][n]; B[M][n]=shmat(segment_id,NULL,0); που μου παρουσιάζει το ίδιο warning. Και στους 2 πίνακες αποθηκεύω int μεταβλητές που παίρνω απο αρχείο .txt . Για την ακρίβεια το πρόγραμμα μου όταν εμφανίζει τα περιεχόμενα των 2 πινάκων κάνει λάθος στο Α[0][0] (εμφανίζει έναν αριθμό -231425626 ενώ το περιεχόμενο είναι 1), τα υπόλοιπα στοιχεία τα εμφανίζει σωστά.
defacer Δημοσ. 30 Νοεμβρίου 2011 Δημοσ. 30 Νοεμβρίου 2011 Αν δεν κάνω λάθος, η shmat επιστρέφει When successful, the segment start address of the attached shared memory segment or mapped file is returned. Otherwise, the shared memory segment is not attached, the errno global variable is set to indicate the error, and a value of -1 is returned. Επομένως διάβασε πάλι την προηγούμενη απάντηση. Απο κει και πέρα δε μπορώ να σε βοηθήσω περισσότερο πέραν του να πω ότι μου φαίνεται πως διαβάζεις από αρχείο κάνοντάς το memory map (υπάρχει λόγος?) και χωρίς να έχεις κατανοήσει πώς λειτουργούν τα memory mapped files. Αν είναι έτσι δες κάποιο σχετικό tutorial.
giampoul Δημοσ. 30 Νοεμβρίου 2011 Μέλος Δημοσ. 30 Νοεμβρίου 2011 Αν δεν κάνω λάθος, η shmat επιστρέφει Επομένως διάβασε πάλι την προηγούμενη απάντηση. Απο κει και πέρα δε μπορώ να σε βοηθήσω περισσότερο πέραν του να πω ότι μου φαίνεται πως διαβάζεις από αρχείο κάνοντάς το memory map (υπάρχει λόγος?) και χωρίς να έχεις κατανοήσει πώς λειτουργούν τα memory mapped files. Αν είναι έτσι δες κάποιο σχετικό tutorial. Από το txt διαβάζω με fscanf() τους πίνακες... Είμαι αρχάριος, δεν ξέρω τι είναι το memory map, αν θες να δεις περίπου το πρόγραμμα μου είναι αυτό...
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα