Advertisement
Nickel59

Untitled

Dec 6th, 2024
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.19 KB | None | 0 0
  1. #include <inttypes.h>
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <vcruntime.h>
  8.  
  9. #define lengthof(x) (sizeof(x) / sizeof(*(x)))
  10.  
  11. void *safemalloc(size_t size) {
  12.   void *block = malloc(size);
  13.   if (!block) {
  14.     (void)fputs("Memory allocation has failed.", stderr);
  15.     abort();
  16.   }
  17.   return block;
  18. }
  19.  
  20. void *saferealloc(void *block, size_t size) {
  21.   char *newBlock = realloc(block, size);
  22.   if (!newBlock) {
  23.     (void)fputs("Memory reallocation has failed.", stderr);
  24.     abort();
  25.   }
  26.   return newBlock;
  27. }
  28.  
  29. char *input(uint16_t maxLength) {
  30.   if (!maxLength) {
  31.     return NULL;
  32.   }
  33.   int32_t inputStringSize = maxLength + 2;
  34.   char *inputString = safemalloc(inputStringSize);
  35.   if (!fgets(inputString, inputStringSize, stdin)) {
  36.     free(inputString);
  37.     while (getchar() != '\n') {
  38.     }
  39.     return NULL;
  40.   }
  41.   if (inputString[0] == '\n') {
  42.     free(inputString);
  43.     return NULL;
  44.   }
  45.   size_t inputStringLength = strlen(inputString);
  46.   char *lastStringCharacterPtr = &(inputString[inputStringLength - 1]);
  47.   if (*lastStringCharacterPtr != '\n') {
  48.     free(inputString);
  49.     while (getchar() != '\n') {
  50.     }
  51.     return NULL;
  52.   }
  53.   *lastStringCharacterPtr = '\0';
  54.   return saferealloc(inputString, inputStringLength);
  55. }
  56.  
  57. uint64_t abs64(int64_t integer) { return integer < 0 ? -(uint64_t)integer : integer; }
  58.  
  59. typedef struct {
  60.   int64_t integer;
  61.   const char *error;
  62. } StringToIntResult;
  63. StringToIntResult *stringToInt(const char *string) {
  64.   StringToIntResult *result = safemalloc(sizeof(StringToIntResult));
  65.   if (!string) {
  66.     *result = (StringToIntResult){0, "Passed NULL."};
  67.     return result;
  68.   }
  69.   if (string[0] == '\0') {
  70.     *result = (StringToIntResult){0, "Invalid string."};
  71.     return result;
  72.   }
  73.   bool startsWithNegativeSign = (string[0] == '-');
  74.   if (startsWithNegativeSign) {
  75.     string = string + 1;
  76.   }
  77.   uint64_t maxInt = abs64(startsWithNegativeSign ? INT64_MIN : INT64_MAX);
  78.   uint8_t maxDigitNumber = snprintf( // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  79.       NULL, 0, "%" PRIu64, maxInt);
  80.   size_t stringLength = strlen(string);
  81.   if (stringLength == 0 || string[0] == '0' || stringLength > maxDigitNumber) {
  82.     *result = (StringToIntResult){0, "Invalid string."};
  83.     return result;
  84.   }
  85.   for (uint32_t i = 0; i < stringLength; ++i) {
  86.     if (string[i] < '0' || string[i] > '9') {
  87.       *result = (StringToIntResult){0, "The string contains non numerical characters."};
  88.       return result;
  89.     }
  90.   }
  91.   if (stringLength == maxDigitNumber) {
  92.     char *maxString = safemalloc(maxDigitNumber + 1);
  93.     (void)snprintf(maxString, // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  94.                    maxDigitNumber + 1, "%" PRIu64, maxInt);
  95.     for (uint32_t i = 0; i < stringLength; ++i) {
  96.       if (string[i] > maxString[i]) {
  97.         free(maxString);
  98.         *result = (StringToIntResult){0, "The resulting integer is too large."};
  99.         return result;
  100.       }
  101.     }
  102.     free(maxString);
  103.   }
  104.   int64_t integer = strtoll(string, NULL, 10);
  105.   if (startsWithNegativeSign) {
  106.     integer = -integer;
  107.   }
  108.   *result = (StringToIntResult){integer, NULL};
  109.   return result;
  110. }
  111.  
  112. typedef struct {
  113.   uint32_t previousElement;
  114.   uint32_t nextElement;
  115. } Result;
  116. Result findNeighbouringElements(uint32_t element) {
  117.   uint32_t fibs[] = {1, 1};
  118.   uint32_t fib = 0;
  119.   while (fibs[1] != element) {
  120.     fib = fibs[0];
  121.     fibs[0] = fibs[1];
  122.     fibs[1] += fib;
  123.   }
  124.   return (Result){fibs[0], fibs[0] += fibs[1]};
  125. }
  126.  
  127. int main() {
  128.   printf("Enter a Fibonacci sequence member >>> ");
  129.   char *inputString = input(9);
  130.   if (!inputString) {
  131.     puts("Invalid input.");
  132.     return 1;
  133.   }
  134.   StringToIntResult *stringToIntResult = stringToInt(inputString);
  135.   free(inputString);
  136.   if (stringToIntResult->error) {
  137.     puts(stringToIntResult->error);
  138.     free(stringToIntResult);
  139.     return 1;
  140.   }
  141.   Result result = findNeighbouringElements(stringToIntResult->integer);
  142.   free(stringToIntResult);
  143.   printf("Previous element: %" PRIu32 " Next element: %" PRIu32, result.previousElement, result.nextElement);
  144.   return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement