ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

...ασύγχρονα μαθήματα γλώσσας C

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Vegeta » 10 Απρ 2013, 12:49

έχω μια απορία η οποία δεν είμαι σίγουρος αν έχει να κάνει 100% με C ή με τις εντολές που δίνουμε στο terminal των ubuntu γενικότερα...
έχω ένα πρόγραμμα στο οποίο θέλω να διαβάζονται τα στοιχεία εισόδου από ένα αρχείο. πρέπει να δώσω στο terminal:
./<όνομα_προγράμματος> <όνομα_αρχείου.txt>

π.χ.: ./program1 arxeio1.txt
τι σημαίνει αυτό? ότι καλεί να τρέξει το πρόγραμμα "program1" έχοντας ως όρισμα το "αρχείο1.txt"? τα ορίσματα οποιουδήποτε προγράμματος δεν δίνονται μέσα στον κώδικα του προγράμματος και όχι από το terminal? πως συνδέεται το arxeio1.txt με το πρόγραμμα, ως είσοδος, με αυτή την εντολή?
Linux: Καλά | Προγραμματισμός: Καλά | Αγγικά: Καλά
Asus TUF Gaming A15 FA506IV-HN216T (Ryzen 9-4900H/16GB/512GB/GeForce RTX 2060/FHD/W10)
Ubuntu 20.04.1 LTS
Άβαταρ μέλους
Vegeta
babeTUX
babeTUX
 
Δημοσιεύσεις: 83
Εγγραφή: 25 Μαρ 2010, 13:49
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό clepto » 10 Απρ 2013, 14:35

το αρχείο1.txt είναι παράμετρος..
το πρόγραμμα που τρέχεις έχει την δυνατότητα να δέχεται μια (ή και περισσότερες) παραμέτρους όταν καλείται..
οι παράμετροι αυτοί αποθηκεύονται αν δεν κάνω λάθος στον πίνακα args[] που έχει ως παράμετρο η main()..
το αν το πρόγραμμα σου θα δέχεται παραμέτρους ή όχι είναι δικιά σου επιλογή και εξαρτάται από τι θες να κάνεις.
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Ilias95 » 10 Απρ 2013, 15:03

Ναι, τα ορίσματα περνιούνται απ' την γραμμή εντολών και μπορείς να τα επεξεργαστείς μέσα απ' το πρόγραμμα σου.

Όταν δηλώνεις την main σαν:
Κώδικας: Επιλογή όλων
int main(int argc, char *argv[])

τότε argc είναι ο αριθμός των ορισμάτων και argv μια array από pointers που δείχνουν στα command line arguments.

Με το παρακάτω sample μπορείς να δεις πως γίνεται να εκτυπώσεις τα ορίσματα που θα περάσεις στο πρόγραμμα σου:
Κώδικας: Επιλογή όλων
#include <stdio.h>

int main(int argc, char *argv[])
{
   register int i;

   for (i = 1; i < argc; i++)
      printf("%s\n", argv[i]);

   return 0;
}

Πρόσεξε ότι ξεκινάω να διαβάζω τα ορίσματα απ' το 2ο, μιας και το 1ο είναι το όνομα του αρχείου.
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Vegeta » 10 Απρ 2013, 17:36

μπορούμε να κάνουμε ένα πολύ απλό παράδειγμα?:
θέλω δημιουργώ ένα .txt (π.χ.:αρχείο1.txt) το οποίο έχει μέσα γραμμένους δύο αριθμούς χωρισμένους με ένα κενό διάστημα ανάμεσα τους (π.χ.:2 3). θέλω να δημιουργήσω ένα πρόγραμμα (π.χ. πρόσθεση) το οποίο να διαβάζει ως είσοδο τους δύο αυτούς αριθμούς από το αρχείο1.txt, να τους προσθέτει και να εμφανίζει το αποτέλεσμα της πρόσθεσης (δηλαδή 5).

θέλω να τρέξω στο terminal:
Κώδικας: Επιλογή όλων
./πρόσθεση αρχείο1.txt

και να μου εμφανίσει στην από κάτω γραμμή:
Κώδικας: Επιλογή όλων
5

τι πρέπει να γράψω στο συγκεκριμένο παράδειγμα στον κώδικα του προγράμματος "πρόσθεση"?
Linux: Καλά | Προγραμματισμός: Καλά | Αγγικά: Καλά
Asus TUF Gaming A15 FA506IV-HN216T (Ryzen 9-4900H/16GB/512GB/GeForce RTX 2060/FHD/W10)
Ubuntu 20.04.1 LTS
Άβαταρ μέλους
Vegeta
babeTUX
babeTUX
 
Δημοσιεύσεις: 83
Εγγραφή: 25 Μαρ 2010, 13:49
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Ilias95 » 10 Απρ 2013, 20:08

Λοιπόν ο κώδικας θα είναι κάπως έτσι:
Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
int i, a, b;
FILE *fp;

if (argc == 1) {
printf("usage: unleast one file is required\n");
exit(EXIT_FAILURE);
}

for (i = 1; i < argc; i++) {
fp = fopen(argv[i], "r");
if (fp == NULL) {
printf("%s can't be opened\n", argv[1]);
exit(EXIT_FAILURE);
}

fscanf(fp, "%d %d", &a, &b);
printf("%d\n", a+b);
fclose(fp);
}

exit(EXIT_SUCCESS);
}

Καταλαβαίνεις φαντάζομαι ότι arguments είναι το αρχείο ή τα αρχεία που θα περάσεις απ' την γραμμή εντολών.
Τα περιεχόμενα του αρχείου δεν έχουν καμία σχέση. Εσύ τα διαβάζεις και τα επεξεργάζεσαι όπως θες.

Το έκανα να διαβάζεις όσα αρχεία της ίδιας μορφής θες.
Οπότε μπορείς να το καλέσεις ας πούμε:
Κώδικας: Επιλογή όλων
./add file1 file2 file3


Πρόσεξε όμως, χρησιμοποίησα την fscanf() οπότε αν τα αρχεία δεν είναι ακριβώς όπως είπες το πρόγραμμα δεν θα λειτουργήσει σωστά.
Σε πραγματικές εφαρμογές, απέφυγε την χρήση της και διάβασε αλλιώς το αρχείο.
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Vegeta » 10 Απρ 2013, 22:08

ωραίος, αρχίζω να το έχω... βλέπω αν προσθέσω περισσότερα argc μου βγάζει το αποτέλεσμα κάθε ενός ξεχωριστά! από τον κώδικα καταλαβαίνω ότι θεωρεί ως πρώτο argc το ίδιο το πρόγραμμα.
αν θέλω να διαβάσω πολλά δεδομένα από ένα αρχείο (χωρίς να ξέρω εκ των προτέρων συγκεκριμένα τον αριθμό τους), όμως ο αριθμός των δεδομένων αυτών δίνεται μέσα στο αρχείο. τότε θα χρησιμοποιήσω την fscanf() με κάποιο loop ή θα είναι πιο σωστό να χρησιμοποιήσω κάποια άλλη εντολή?
παρόμοιο παράδειγμα με το παραπάνω, για την πρόσθεση αριθμών... αν έχω γραμμένα τα εξής σε ένα αρχείο:
4
2 6 5 8

στην πρώτη σειρά το 4 υποδηλώνει το σύνολο των αριθμών που θέλω να προσθέσω, οι οποίο αριθμοί βρίσκονται στην δεύτερη σειρά. θέλω δηλαδή όταν δίνω ως argc το συγκεκριμένο αρχείο να "βλέπει" το 4 στην πρώτη σειρά, να προσθέτει τους τέσσερις αριθμούς της δεύτερης σειράς και να μου εμφανίζει το αποτέλεσμα (21).
σε αυτή την περίπτωση μπορώ να διαβάσω όλη την δεύτερη σειρά αμέσως (με κάποια εντολή) ή θα βάλω την fscanf() και την εντολή της πρόσθεσης μέσα σε ένα loop για να διαβάσει και να προσθέσει όσες φορές γράφει στην πρώτη σειρά?
Linux: Καλά | Προγραμματισμός: Καλά | Αγγικά: Καλά
Asus TUF Gaming A15 FA506IV-HN216T (Ryzen 9-4900H/16GB/512GB/GeForce RTX 2060/FHD/W10)
Ubuntu 20.04.1 LTS
Άβαταρ μέλους
Vegeta
babeTUX
babeTUX
 
Δημοσιεύσεις: 83
Εγγραφή: 25 Μαρ 2010, 13:49
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Ilias95 » 10 Απρ 2013, 22:41

Vegeta έγραψε:από τον κώδικα καταλαβαίνω ότι θεωρεί ως πρώτο argc το ίδιο το πρόγραμμα.

Σωστά, το όνομα του προγράμματος θεωρείται πάντα το πρώτο cla (command line argument).
Vegeta έγραψε:θέλω δηλαδή όταν δίνω ως argc το συγκεκριμένο αρχείο

Ως cla θες να πεις.

argc σημαίνει arguments count και είναι απλά ένας ακέραιος αριθμός που δείχνει πόσα ορίσματα περάστηκαν στο σύνολο.
Btw, τα argc και argv δεν είναι υποχρεωτικά ονόματα, χρησιμοποιούνται όμως πάντα έτσι από σύμβαση.
Αν θέλεις δηλαδή μπορείς να τα αλλάξεις με οποιοδήποτε άλλο όνομα μεταβλητής, μην το κάνεις όμως.

Σχετικά με τα επόμενα που ρωτάς πρόκειται για κάποια εργασία που έχεις να κάνεις ή απλά το κάνεις για να πειραματιστείς;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 10 - ΑΡΧΕΙΑ

Δημοσίευσηαπό Vegeta » 11 Απρ 2013, 23:05

εργασία είναι, όχι δικιά μου, απλά την είδα κάπου και μπήκα στο τρυπάκι. θα το παλέψω μόνος μου. ευχαριστώ για την βοήθεια. αν υπάρξει θέμα θα επανέλθω!
Linux: Καλά | Προγραμματισμός: Καλά | Αγγικά: Καλά
Asus TUF Gaming A15 FA506IV-HN216T (Ryzen 9-4900H/16GB/512GB/GeForce RTX 2060/FHD/W10)
Ubuntu 20.04.1 LTS
Άβαταρ μέλους
Vegeta
babeTUX
babeTUX
 
Δημοσιεύσεις: 83
Εγγραφή: 25 Μαρ 2010, 13:49
Εκτύπωση

Προηγούμενη

Επιστροφή στο Μαθήματα C