/[cvs]/joko/Uni/BSArch/01/prime.c
ViewVC logotype

Annotation of /joko/Uni/BSArch/01/prime.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (hide annotations)
Mon May 15 11:36:52 2006 UTC (18 years, 6 months ago) by franky
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +5 -2 lines
File MIME type: text/plain
*** empty log message ***

1 franky 1.17 /* $Id: prime.c,v 1.16 2006/05/15 11:27:10 franky Exp $ */
2 joko 1.5
3 joko 1.1 #include <stdio.h>
4 joko 1.6 #include <stdlib.h>
5 franky 1.14 #include <math.h>
6 joko 1.6 #include <limits.h>
7 joko 1.9 #include <errno.h>
8 joko 1.3
9 joko 1.13 #ifdef _MSC_VER
10     #define snprintf _snprintf
11     #endif
12    
13 joko 1.6 #define BOOL int
14     #define TRUE 1
15     #define FALSE 0
16    
17     #define PRINTPRIME(x) if (is_prime(x)) printf("%i\n", x)
18 joko 1.5 #define PRINTERROR(message) fprintf(stderr, "ERROR: %s\n", message)
19 joko 1.10 #define PRINTWARNING(message) fprintf(stderr, "WARNING: %s\n", message)
20 joko 1.4
21 joko 1.11 #define MAX_LINE_LENGTH 80
22    
23    
24 joko 1.5 /* check for prime number */
25 joko 1.6 BOOL is_prime(long int number)
26 joko 1.1 {
27 franky 1.14 int i,sq;
28 joko 1.9 /* negative values, 0 and 1 are never prime numbers */
29 joko 1.7 if (number < 2) return FALSE;
30 franky 1.14 sq=sqrt(number);
31 joko 1.7
32     /* check all numbers 2..sqrt(number) for being a prime number */
33 franky 1.14 for (i=2; i <= sq; i++) {
34 joko 1.4 if ((number % i) == 0)
35 joko 1.6 return FALSE;
36     }
37     return TRUE;
38     }
39    
40 joko 1.7 /* convert from string to long int, with error checking */
41 franky 1.14 long int convert_number(const char *nptr, BOOL warn) {
42 joko 1.9
43     char * endptr;
44 franky 1.15 long int number;
45    
46 franky 1.16 errno = 0;
47 franky 1.15 number = strtol(nptr, &endptr, 10);
48 joko 1.9
49     /* invalid characters? */
50     if (*endptr != '\0') {
51 franky 1.14 char message[256];
52     snprintf(message, 255, "Could not convert '%s' to a valid (integer) number.", nptr);
53 franky 1.17 errno=EINVAL;
54 franky 1.14 if(warn)
55     PRINTWARNING(message);
56     else{
57     PRINTERROR(message);
58     exit(EXIT_FAILURE);
59     }
60 joko 1.9 }
61    
62     /* invalid range? */
63     /* if (number == LONG_MAX || number == LONG_MIN) { */
64     if (errno == ERANGE) {
65 franky 1.14 char message[256];
66     snprintf(message, 255, "Number is not in range of 'long int': %s", nptr);
67 franky 1.17 errno=EINVAL;
68 franky 1.14 if(warn)
69     PRINTWARNING(message);
70     else{
71     PRINTERROR(message);
72     exit(EXIT_FAILURE);
73     }
74 joko 1.4 }
75 joko 1.9
76     return number;
77    
78 joko 1.1 }
79 joko 1.3
80 joko 1.1 int main(int argc, char * argv[])
81     {
82 joko 1.4
83     if (argc == 1) {
84 joko 1.6 PRINTERROR("No arguments given.");
85 joko 1.9 exit(EXIT_FAILURE);
86 joko 1.4 }
87    
88 joko 1.5 /* (3) range mode */
89 joko 1.4 if (argc > 2) {
90 joko 1.7 long int i, j;
91 franky 1.14 i = convert_number(argv[1],FALSE);
92     j = convert_number(argv[2],FALSE);
93 joko 1.9 for (i; i< j; i++) {
94 joko 1.1 PRINTPRIME(i);
95     }
96 joko 1.4
97 joko 1.5 /* other modes */
98 joko 1.4 } else {
99 franky 1.14 int err;
100 joko 1.5 /* try to open file for reading */
101 joko 1.4 FILE * fp = fopen(argv[1], "r");
102 franky 1.14 err=errno;
103 franky 1.17 errno=0;
104 joko 1.5 /* (1) test-single-number mode: first argument is not a filename */
105 joko 1.4 if (fp == NULL) {
106 franky 1.14 long int number = convert_number(argv[1],TRUE);
107 franky 1.17 if(errno){
108 franky 1.14 fprintf(stderr, "%s: %s\n", argv[1], strerror(err));
109     return -1;
110     }
111 joko 1.7 PRINTPRIME(number);
112 joko 1.4
113 joko 1.5 /* (2) file mode: read numbers from file */
114 joko 1.4 } else {
115 joko 1.11 char line[MAX_LINE_LENGTH + 1];
116 joko 1.10 long int number;
117 joko 1.11 int line_length;
118     long int line_no = 0;
119     while (fgets(line, MAX_LINE_LENGTH + 1, fp)) {
120 joko 1.10
121     /* count line number (for warnings) */
122 joko 1.11 line_no++;
123 joko 1.10
124 joko 1.11 line_length = strlen(line);
125    
126 joko 1.10 /* skip empty lines */
127 joko 1.11 if (strlen(line) < 2) continue;
128 joko 1.10
129     /* line handling: policy = skip exceeding lines */
130    
131     /* line exceeds max length */
132 joko 1.11 if (line_length == MAX_LINE_LENGTH && line[line_length-1] != '\n') {
133 joko 1.10 char message[254];
134 joko 1.11 snprintf(message, 256, "Line too long (max %i chars) in line number: %i", MAX_LINE_LENGTH, line_no);
135 joko 1.10 PRINTWARNING(message);
136    
137 joko 1.11 /* eat all characters until newline or EOF */
138     while (1) {
139     int charcode = fgetc(fp);
140     if (charcode == 10 || charcode == EOF) break;
141     }
142 joko 1.10
143     /* skip this line from prime calculation */
144     continue;
145     }
146    
147 joko 1.11 /* if last char is newline, strip it */
148     if (line[line_length-1] == '\n') {
149     line[line_length-1] = '\0';
150     }
151    
152     /* finally: prime number calculation and output */
153 franky 1.14 number = convert_number(line,FALSE);
154 joko 1.7 PRINTPRIME(number);
155 joko 1.11
156 joko 1.5 }
157 joko 1.1 fclose(fp);
158     }
159     }
160     }

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed