/[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.13 - (hide annotations)
Sat May 13 18:53:54 2006 UTC (18 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.12: +5 -1 lines
File MIME type: text/plain
+ compiles with vc/win32

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

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