Σημειώσεις - Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 9: Είσοδος και έξοδος

Είσοδος και έξοδος

Μία επισήμανση που πρέπει να γίνει είναι ότι δεν μπορούμε να χρησιμοποιήσουμε οποιαδήποτε συνάρτηση σε οποιοδήποτε ρεύμα. Εξαρτάται από το mode που δόθηκε όταν άνοιξε το αντίστοιχο αρχείο.

Αντιγραφή αρχείων

/* File: filecopy.c */
#include <stdio.h>

int main(int argc, char *argv[])
{ FILE *ifp, *ofp;
  int n;
  char buf[1024];
  if (argc != 3) {
    fprintf(stderr,
            "Usage: %s <soure-file> <target-file>\n", argv[0]);
    return 1;
  }
  if ((ifp = fopen(argv[1], "rb")) == NULL) { /* Open source file */
    perror("fopen source-file");
    return 1;
  }
  if ((ofp = fopen(argv[2], "wb")) == NULL) { /* Open target file */
    perror("fopen target-file");
    return 1;
  }
  while (!feof(ifp)) {  /* While we don't reach the end of source */
               /* Read characters from source file to fill buffer */
    n = fread(buf, sizeof(char), sizeof(buf), ifp);
                          /* Write characters read to target file */
    fwrite(buf, sizeof(char), n, ofp);
  }
  fclose(ifp);
  fclose(ofp);
  return 0;
}
% gcc -o filecopy filecopy.c
% ./filecopy
Usage: ./filecopy <soure-file> <target-file>
% ./filecopy bla foo
fopen source-file: No such file or directory
%
% cat helloworld.c
/* File: helloworld.c */
#include <stdio.h>

main()
{ printf("Hello world\n");
}
% ./filecopy helloworld.c newhelloworld.c
% cat newhelloworld.c
/* File: helloworld.c */
#include <stdio.h>

main()
{ printf("Hello world\n");
}
% ls -l helloworld.c newhelloworld.c
-rw-------   1 ip       www           81 Dec 18 21:45 newhelloworld.c
-rw-r-----   1 ip       www           81 Oct 13 12:42 helloworld.c
% diff helloworld.c newhelloworld.c
%
% ./filecopy filecopy Copy\ of\ filecopy
% ls -l filecopy Copy\ of\ filecopy
-rw-------   1 ip       www         6884 Dec 18 21:46 Copy of filecopy
-rwx------   1 ip       www         6884 Dec 18 21:34 filecopy*
% cmp filecopy Copy\ of\ filecopy
%

Εκτύπωση γραμμών εισόδου με αντίστροφη σειρά

/* File: revinput.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Slistnode *SListptr;

struct Slistnode {                    /* A list node structure */
  char *line;                       /* with a string as member */
  SListptr next;
};

void Sinsert_at_start(SListptr *, char *);
void Sprint(SListptr);

int main(void)
{ char buf[1024];
  SListptr list;
  list = NULL;    /* Initialize list to store lines to be read */
  while (fgets(buf, sizeof buf, stdin) != NULL) /* Read a line */
                     /* and insert it at the start of the list */
    Sinsert_at_start(&list, buf);
  Sprint(list);     /* Print the list, i.e. the input reversed */
  return 0;
}

void Sinsert_at_start(SListptr *ptraddr, char *buf)
                    /* The well-known insert_at_start function */
{ SListptr templist;
  templist = *ptraddr;
  *ptraddr = malloc(sizeof(struct Slistnode));
  (*ptraddr)->line = malloc((strlen(buf)+1) * sizeof(char));
  strcpy((*ptraddr)->line, buf);
  (*ptraddr)->next = templist;
}

void Sprint(SListptr list)          /* Just print out the list */
{ while (list != NULL) {
    printf("%s", list->line);
    list = list->next; }
}
% gcc -o revinput revinput.c
% ./revinput
These are some lines
to test program revinput.
Ok, one more line.
These are my last words
before the minus signs
---------------------------
^D
---------------------------
before the minus signs
These are my last words
Ok, one more line.
to test program revinput.
These are some lines
%
% cat helloworld.c
/* File: helloworld.c */
#include <stdio.h>

main()
{ printf("Hello world\n");
}
%
% ./revinput < helloworld.c
}
{ printf("Hello world\n");
main()

#include <stdio.h>
/* File: helloworld.c */
  1. Υπάρχει και η “αδελφή” συνάρτηση char *gets(char *s), για την ανάγνωση από το stdin μίας συμβολοσειράς, αλλά δεν πρέπει να χρησιμοποιείται, για λόγους ασφαλείας. Μάλιστα, ο gcc δίνει σχετική προειδοποίηση όταν χρησιμοποιούμε αυτήν τη συνάρτηση σ’ ένα πρόγραμμα. Αντ’ αυτής, θα δούμε στη συνέχεια την ασφαλή συνάρτηση fgets. ↩

  2. δεκαδικών για μετατροπές f, e ή E ή σημαντικών για μετατροπές g ή G ↩

  3. αν δεν δοθεί ακρίβεια, αυτή θεωρείται ίση με 6 ↩

  4. κενό, στηλογνώμονας ή αλλαγή γραμμής ↩

  5. Επισήμως, υπάρχει και η συνάρτηση char *gets(char *buf), η οποία κάνει περίπου ό,τι και η fgets. Διαβάζει από το ρεύμα stdin, χωρίς να βάζει κάποιο πάνω όριο στο πλήθος των χαρακτήρων που θα διαβαστούν και, γι’ αυτό ακριβώς, για λόγους ασφαλείας, αποθαρρύνεται η χρήση της. Επίσης, η gets δεν τοποθετεί τον χαρακτήρα αλλαγής γραμμής (\n) που διάβασε μέσα στο buf. Αν θέλουμε να διαβάσουμε μία γραμμή χαρακτήρων από την πρότυπη είσοδο, μπορούμε να χρησιμοποιήσουμε την fgets, δίνοντας σαν τελευταίο όρισμα το stdin, αντί να χρησιμοποιήσουμε την gets. ↩

  6. Ο τύπος size_t είναι ο unsigned int, typedef’ed. ↩

Κατεβάστε το κεφάλαιο: PDF · Markdown