Browse Source

check input of n and values from stdin

Chris Cromer 7 months ago
parent
commit
bdb847e6d9
Signed by: Chris Cromer <chris@cromer.cl> GPG Key ID: 39CC813FF3C8708A
1 changed files with 94 additions and 20 deletions
  1. 94
    20
      src/sort.c

+ 94
- 20
src/sort.c View File

@@ -17,6 +17,8 @@
17 17
 #include <stdlib.h>
18 18
 #include <getopt.h>
19 19
 #include <string.h>
20
+#include <errno.h>
21
+#include <limits.h>
20 22
 #include "random.h"
21 23
 #include "timer.h"
22 24
 #include "bubble_sort.h"
@@ -27,9 +29,12 @@
27 29
 #define SORT_VERSION "1.0.0"
28 30
 
29 31
 /**
30
- * El array a ordenar
32
+ * El array desordenado
31 33
  */
32 34
 static int *unordered_array;
35
+/**
36
+ * El array a ordenar
37
+ */
33 38
 static int *work_array;
34 39
 
35 40
 /**
@@ -72,33 +77,66 @@ void print_array(int *array, int n) {
72 77
  * @return Retorna 1 si es exitosa ó 0 si falla
73 78
  */
74 79
 int read_buffer(int *variable) {
75
-	char buffer[12];
80
+	char buffer[32];
81
+	char *check;
76 82
 	while (1) {
77
-		if (fgets(buffer, 12, stdin) != NULL) {
83
+		if (fgets(buffer, 32, stdin) != NULL) {
78 84
 			if (buffer[strlen(buffer) - 1] == '\n') {
79 85
 				buffer[strlen(buffer) - 1] = '\0';
80 86
 				break;
81 87
 			}
82 88
 		}
83 89
 	}
84
-	char **check = malloc(sizeof(char**));
85
-	if (check == NULL) {
86
-		fprintf(stderr, "Error: Out of heap space!\n");
87
-		exit(5);
90
+	errno = 0;
91
+	long input = strtol(buffer, &check, 10);
92
+	if (buffer == check) {
93
+		// Empty
94
+		return 0;
95
+	}
96
+	else if (errno == ERANGE && input == LONG_MIN) {
97
+		// Overflow
98
+		return 0;
99
+	}
100
+	else if (errno == ERANGE && input == LONG_MAX) {
101
+		// Underflow
102
+		return 0;
103
+	}
104
+	else if (errno == EINVAL) {  /* not in all c99 implementations - gcc OK */
105
+		// Base contains unsupported value
106
+		// This check is not in all c99 implementations, but does exist in gcc
107
+		return 0;
108
+	}
109
+	else if (errno != 0 && input == 0) {
110
+		// Unspecified error
111
+		return 0;
88 112
 	}
89
-	long input = strtol(buffer, check, 10);
90
-	if (*check[0] == '\0') {
91
-		free(check);
113
+	else if (errno == 0 && !*check) {
114
+		// Valid number
115
+		if (input > INT_MAX || input < INT_MIN) {
116
+			fprintf(stderr, "Error: n tiene que ser menor de 2147483648 y mayor de -2147483649!\n");
117
+			return 0;
118
+		}
92 119
 		*variable = (int) input;
93 120
 		return 1;
94 121
 	}
122
+	else if (errno == 0 && *check != 0) {
123
+		// Contains non number characters
124
+		return 0;
125
+	}
95 126
 	else {
96
-		free(check);
97 127
 		return 0;
98 128
 	}
99 129
 }
100 130
 
101 131
 /**
132
+ * Imprimir un mensaje y salir si n es invalido
133
+ */
134
+void print_invalid_n() {
135
+	fprintf(stderr, "Error: El valor de n es invalido!\n");
136
+	exit(7);
137
+}
138
+
139
+/**
102 140
  * Liberar la memoria al salir
103 141
  */
104 142
 void cleanup() {
@@ -112,7 +150,9 @@ void cleanup() {
112 150
  * @return Retorna el codigo de error o 0 por exito
113 151
  */
114 152
 int main (int argc, char **argv) {
115
-	long long i;
153
+	char *check = NULL;
154
+	long ninput = 0;
155
+	int i;
116 156
 	int n = 10;
117 157
 	int elegir = 0;
118 158
 	int imprimir = 0;
@@ -173,10 +213,44 @@ int main (int argc, char **argv) {
173 213
 				selection = 1;
174 214
 				break;
175 215
 			case 'n':
176
-				n = atol(optarg);
177
-				if (n <= 1) {
178
-					fprintf(stderr, "Error: n tiene que ser mayor de 1!\n");
179
-					return 3;
216
+				errno = 0;
217
+				ninput = strtol(optarg, &check, 10);
218
+				if (optarg == check) {
219
+					// Empty
220
+					print_invalid_n();
221
+				}
222
+				else if (errno == ERANGE && ninput == LONG_MIN) {
223
+					// Overflow
224
+					print_invalid_n();
225
+				}
226
+				else if (errno == ERANGE && ninput == LONG_MAX) {
227
+					// Underflow
228
+					print_invalid_n();
229
+				}
230
+				else if (errno == EINVAL) {  /* not in all c99 implementations - gcc OK */
231
+					// Base contains unsupported value
232
+					// This check is not in all c99 implementations, but does exist in gcc
233
+					print_invalid_n();
234
+				}
235
+				else if (errno != 0 && ninput == 0) {
236
+					// Unspecified error
237
+					print_invalid_n();
238
+				}
239
+				else if (errno == 0 && optarg && !*check) {
240
+					// Valid number
241
+					if (ninput > INT_MAX || ninput < INT_MIN) {
242
+						fprintf(stderr, "Error: n tiene que ser menor de 2147483648!\n");
243
+						return 6;
244
+					}
245
+					n = (int) ninput;
246
+					if (n <= 1) {
247
+						fprintf(stderr, "Error: n tiene que ser mayor de 1!\n");
248
+						return 3;
249
+					}
250
+				}
251
+				else if (errno == 0 && optarg && *check != 0) {
252
+					// Contains non number characters
253
+					print_invalid_n();
180 254
 				}
181 255
 				break;
182 256
 			case 'e':
@@ -217,15 +291,15 @@ int main (int argc, char **argv) {
217 291
 	for (i = 0; i < n; i++) {
218 292
 		if (elegir) {
219 293
 			opt = 0;
220
-			fprintf(stdout, "Elegir elemento %lli: ", i + 1);
294
+			fprintf(stdout, "Elegir elemento %d: ", i + 1);
221 295
 			while (!read_buffer(&opt)) {
222
-				fprintf(stdout, "Número invalido! Tiene que ser mayor de 1!\n");
223
-				fprintf(stdout, "Elegir elemento %lli: ", i + 1);
296
+				fprintf(stdout, "Número invalido! Tiene que ser mayor de -2147483649 y menor de 2147483648!\n");
297
+				fprintf(stdout, "Elegir elemento %d: ", i + 1);
224 298
 			}
225 299
 			unordered_array[i] = opt;
226 300
 		}
227 301
 		else {
228
-			unordered_array[i] = gen_rand((n * 10) * -1, n * 10);
302
+			unordered_array[i] = gen_rand(-100000000, 100000000);
229 303
 		}
230 304
 	}
231 305
 

Loading…
Cancel
Save