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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Sat May 13 18:53:54 2006 UTC (18 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.12: +5 -1 lines
File MIME type: text/plain
+ compiles with vc/win32

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

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