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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.16

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