fork(1) download
  1. /* -----------------------------------------------------------------------------------
  2.  * Παράδειγμα κώδικα σε C για...
  3.  * το διάβασμα μιας γραμμής από την κύρια είσοδο
  4.  * αποθήκευσή της σε ένα string (linebuf)
  5.  * διάσπασή της σε επί μέρους λέξεις (stokens)
  6.  * μετατροπή της κάθε λέξης σε διάφορους τύπους αριθμών (με και χωρίς έλεγχο)
  7.  * τύπωμα των αποτελεσμάτων στην οθόνη
  8.  *
  9.  * Για απλές μετατροπές ενεργοποιήστε τη συνάρτηση: print_conv1simple()
  10.  * Για προχωρημένες μετατροπές ενεργοποιήστε τη συνάρτηση: print_conv2advanced()
  11.  *
  12.  * ( και οι 2 παραπάνω συναρτήσεις βρίσκονται απενεργοποιημένες μέσα σε σχόλια
  13.  * στην συνάρτηση main() στις γραμμές 198 και 207, αντίστοιχα )
  14.  * -----------------------------------------------------------------------------------
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21.  
  22. #define MAXLINE 255+1 // μέγιστο μήκος για τη γραμμή εισόδου
  23. #define MAXTOKENS 3 // μέγιστο πλήθος tokens (λέξεων) ανά γραμμή
  24.  
  25. // Πρότυπα Συναρτήσεων
  26.  
  27. char *s_get(char */*s*/, int /*maxlen*/);
  28. int s_tokenize(char */*s*/, char *[]/*tokens*/, int /*maxtokens*/, char */*delims*/);
  29. void print_conv1simple( int /*ntokens*/, char *[]/*tokens*/ );
  30. void print_conv2advanced( int /*ntokens*/, char *[]/*tokens*/ );
  31.  
  32.  
  33. // -----------------------------------------------------------------------------------
  34. // Διάβασμα του string s από την κύρια είσοδο, μέχρι να πατηθεί ENTER ή μέχρι να
  35. // συμπληρωθούν maxlen-1 χαρακτήρες. Επιστρέφει το διαβασμένο s με μηδενισμένο τον
  36. // τελευταίο χαρακτήρα (αν ήταν '\n' έχει αντικατασταθεί από '\0')
  37. //
  38. char *s_get(char *s, int maxlen)
  39. {
  40. register int i;
  41.  
  42. for (i=0; (s[i]=getchar()) != '\n' && i < maxlen-1; i++)
  43. ; // for-loop με κενό σώμα
  44. s[i] = '\0'; // μηδενισμός τελικού χαρακτήρα
  45.  
  46. return s;
  47. }
  48.  
  49. // -----------------------------------------------------------------------------------
  50. // Διάσπαση του s σε έως maxtokens λέξεις, οι οποίες αποθηκεύονται στον πίνακα tokens[].
  51. // Χαρακτήρες διαχωρισμού των tokens λογίζονται όσοι περιέχονται στο string delimiters.
  52. // Επιστρέφει το πλήθος των tokens (λέξεων).
  53. // ΣΗΜΑΝΤΙΚΟ: μετά το πέρας της συνάρτησης το αρχικο s έχει κατακερματιστεί (αν
  54. // αυτό δεν είναι επιθυμητο, τότε θα πρέπει να περαστεί στην συνάρτηση
  55. // κάποιο αντίγραφο του s).
  56. //
  57. int s_tokenize(char *s, char *tokens[], int maxtokens, char *delimiters)
  58. {
  59. register int i=0;
  60.  
  61. tokens[0] = strtok(s, delimiters); // αποθήκευση 1ου token
  62. if (tokens[0] == NULL) // αποτυχία, πρόωρη έξοδος
  63. return 0;
  64. // αποθήκευση υπόλοιπων (έως maxtokens)
  65. for (i=1; i < maxtokens && (tokens[i]=strtok(NULL, delimiters)) != NULL; i++)
  66. ; // for-loop με κενό σώμα
  67.  
  68. return i;
  69. }
  70.  
  71. // -----------------------------------------------------------------------------------
  72. // Απλή μετατροπή & τύπωμα των tokens ως int, long int και double, χρησιμοποιώντας
  73. // την οικογένεια των στάνταρ συναρτήσεων ato?() ( ορίζονται στο <stdlib.h> )
  74. // ΣΗΜΑΝΤΙΚΟ: Αυτές οι συναρτήσεις δεν δίνουν δυνατότητα ελέγχου για ενδεχόμενη
  75. // αποτυχία της μετροπής. Αυτό το κάνουν οι συναρτήσεις strto?()
  76. // ( δείτε παρακάτω την συνάρτηση: print_conv2advanced() )
  77. //
  78. void print_conv1simple( int ntokens, char *tokens[] )
  79. {
  80. int toi; // για αποθήκευση σε int
  81. long int tol; // για αποθήκευση σε long int
  82. double tod; // για αποθήκευση σε double
  83. register int i; // για να διατρέξουμε τον tokens[]
  84.  
  85. for ( i=0; i < ntokens; i++ ) // όσο υπάρχουν tokens
  86. {
  87. // μετατροπές
  88. toi = atoi( tokens[i] ); // μετατροπή σε int
  89. tol = atol( tokens[i] ); // μετατροπή σε long int
  90. tod = atof (tokens[i] ); // μετατροπή σε double
  91.  
  92. // τύπωμα αποτελεσμάτων
  93. printf("Token #%d: \"%s\"\n", i+1, tokens[i]); // τύπωμα αρχικού token
  94. // τύπωμα των μετατροπών
  95. printf( "as int: %d, as long: %ld, as double: %g\n\n", toi, tol, tod );
  96. }
  97.  
  98. return;
  99. }
  100.  
  101. // -----------------------------------------------------------------------------------
  102. // Προχωρημένη μετατροπή & τύπωμα των tokens ως double, long και unsigned long,
  103. // χρησιμοποιώντας την οικογένεια των στάνταρ συναρτήσεων strto?() ( ορίζονται
  104. // στο <stdlib.h> ).
  105. //
  106. // Oι συναρτήσεις αυτές χρησιμοποιούν την στάνταρ καθολική μεταβλητή errno (ορίζεται
  107. // στο αρχείο <errno.h>) καθώς κι ένα προσωρινό string ( ptail ) ως 2ο όρισμά τους
  108. // προκειμένου να σηματοδοτήσουν ενδεχόμενη αποτυχία της μετατροπής. Το 3ο τους όρισμα
  109. // είναι η αριθμητική βάση για την μετατροπή (δεκαδική, οκταδική, κλπ).
  110. //
  111. // Υποστηρίζουν εντοπιότητες (locale), έλεγχο για λανθασμένη βάση και άλλα, τα οποία
  112. // δεν τα χρησιμοποιώ εδώ.
  113. //
  114. // Για περισσότερες λεπτομέρειες διαβάστε την επίσημη τεκμηρίωσή τους στον compiler σας
  115. // (εναλλακτικά: http://l...content-available-to-author-only...e.net/man/3/strtol )
  116. //
  117. void print_conv2advanced( int ntokens, char *tokens[] )
  118. {
  119. extern int errno; // in <errno.h>
  120.  
  121. double tod; // για αποθήκευση σε double
  122. long int tol; // για αποθήκευση σε long
  123. unsigned long int toul; // για αποθήκευση σε unsigned long
  124. char *ptail; // για έλεγχο περιττών χαρακτήρων
  125. const int base = 10; // αριθμητική βάση για την μετατροπή
  126. register int i; // για να διατρέξουμε τον tokens[]
  127. char errmsg[MAXLINE] = ""; // βοηθητικό string για σφάλματα
  128.  
  129. for ( i=0; i < ntokens; i++ ) // όσο υπάρχουν tokens
  130. {
  131. *errmsg = '\0'; // εκκαθάριση του errmsg
  132.  
  133. // μετατροπή σε double
  134. errno = 0; // εκκαθάριση του errno
  135. tod = strtod( tokens[i], &ptail );
  136. if ( *ptail != '\0' || errno == ERANGE) { // έλεγχος αποτυχίας
  137. if ( tod == 0 )
  138. strncpy(errmsg, "*** double failed ", MAXLINE);
  139. else if (errno == ERANGE)
  140. strncpy(errmsg, "+++ double overflowed ", MAXLINE);
  141. else
  142. strncpy(errmsg, "--- double fixed ", MAXLINE);
  143. }
  144.  
  145. // μετατροπή σε long int
  146. errno = 0; // εκκαθάριση του errno
  147. tol = strtol( tokens[i], &ptail, base );
  148. if ( *ptail != '\0' || errno == ERANGE) { // έλεγχος αποτυχίας
  149. if (tol == 0)
  150. strncat(errmsg, "*** long failed ", MAXLINE-1);
  151. else if (errno == ERANGE)
  152. strncpy(errmsg, "+++ long overflowed ", MAXLINE);
  153. else
  154. strncat(errmsg, "--- long fixed ", MAXLINE-1);
  155. }
  156.  
  157. // μετατροπή σε unsigned long
  158. errno = 0; // εκκαθάριση του errno
  159. toul = strtoul(tokens[i], &ptail, base);
  160. if ( *ptail != '\0' || errno == ERANGE) { // έλεγχος αποτυχίας
  161. if (toul == 0)
  162. strncat(errmsg, "*** unsigned long failed", MAXLINE-1);
  163. else if (errno == ERANGE)
  164. strncpy(errmsg, "+++ unsigned overflowed ", MAXLINE);
  165. else
  166. strncat(errmsg, "--- unsigned long fixed", MAXLINE-1);
  167. }
  168.  
  169. // τύπωμα αποτελεσμάτων
  170. printf("Token #%d: \"%s\"\n", i+1, tokens[i]); // τύπωμα αρχικού token
  171. // τύπωμα των μετατροπών
  172. printf( "as double: %g, as long: %ld, as unsigned long: %lu\n",
  173. tod, tol, toul
  174. );
  175. // τύπωμα του ptail
  176. printf("%s\n(ptail = \"%s\")\n\n", errmsg, ptail );
  177. }
  178.  
  179. return;
  180. }
  181.  
  182. // -----------------------------------------------------------------------------------
  183. int main( void )
  184. {
  185. char linebuf[ MAXLINE ]; // για το διάβασμα της γραμμής ειδόδου
  186. char *stokens[ MAXTOKENS ]; // για την αποθήκευση των tokens
  187. int ntokens = 0; // το πλήθος των διαβασμένων tokens
  188. register int i; // βοηθητικός μετρητής
  189.  
  190. // διάβασμα ολόκληρης της γραμμής εισόδου
  191. printf("Enter up to %d words (tokens): ", MAXTOKENS);
  192. s_get( linebuf, MAXLINE);
  193.  
  194. // διάσπαση σε έως MAXTOKENS λέξεις (διαχωριστικοί χαρακτήρες: space & tabs)
  195. ntokens = s_tokenize( linebuf, stokens, MAXTOKENS, " \t");
  196.  
  197. // τύπωμα των λέξεων στις οποίες διασπάστηκε η γραμμή
  198. printf("\n%d typed token(s):\n", ntokens);
  199. for (i=0; i < ntokens; i++)
  200. printf("\t%s\n", stokens[i] );
  201. putchar('\n');
  202.  
  203. /*
  204. * ΕΝΕΡΓΟΠΟΙΗΣΤΕ τη συνάρτηση που ακολουθεί για απλή μετατροπή των λέξεων
  205. * σε αριθμούς (δηλαδή χωρίς έλεγχο κι ενημέρωση σε περίπτωση αποτυχίας)
  206. */
  207.  
  208. // απλή μετατροπή και τύπωμα των αποτελεσμάτων στην οθόνη
  209. // print_conv1simple( ntokens, stokens ); // απλή μετατροπή
  210.  
  211. /*
  212. * Εναλλακτικά, ΕΝΕΡΓΟΠΟΙΗΣΤΕ τη συνάρτηση που ακολουθεί για προχωρημένη
  213. * μετατροπή των λέξεων σε αριθμούς (δηλαδή, με έλεγχο κι ενημέρωση σε
  214. * περίπτωση αποτυχίας).
  215. */
  216.  
  217. // προχωρημένη μετατροπή και τύπωμά των αποτελεσμάτων στην οθόνη
  218. // print_conv2advanced( ntokens, stokens ); // προχωρημένη μετατροπή
  219.  
  220. printf("\npress ENTER to exit..."); fflush(stdin); getchar();
  221. exit( EXIT_SUCCESS);
  222. }
  223.  
  224.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty