Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <inttypes.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <vcruntime.h>
- #define lengthof(x) (sizeof(x) / sizeof(*(x)))
- void *safemalloc(size_t size) {
- void *block = malloc(size);
- if (!block) {
- (void)fputs("Memory allocation has failed.", stderr);
- abort();
- }
- return block;
- }
- void *saferealloc(void *block, size_t size) {
- char *newBlock = realloc(block, size);
- if (!newBlock) {
- (void)fputs("Memory reallocation has failed.", stderr);
- abort();
- }
- return newBlock;
- }
- char *input(uint16_t maxLength) {
- if (!maxLength) {
- return NULL;
- }
- int32_t inputStringSize = maxLength + 2;
- char *inputString = safemalloc(inputStringSize);
- if (!fgets(inputString, inputStringSize, stdin)) {
- free(inputString);
- while (getchar() != '\n') {
- }
- return NULL;
- }
- if (inputString[0] == '\n') {
- free(inputString);
- return NULL;
- }
- size_t inputStringLength = strlen(inputString);
- char *lastStringCharacterPtr = &(inputString[inputStringLength - 1]);
- if (*lastStringCharacterPtr != '\n') {
- free(inputString);
- while (getchar() != '\n') {
- }
- return NULL;
- }
- *lastStringCharacterPtr = '\0';
- return saferealloc(inputString, inputStringLength);
- }
- uint64_t abs64(int64_t integer) { return integer < 0 ? -(uint64_t)integer : integer; }
- typedef struct {
- int64_t integer;
- const char *error;
- } StringToIntResult;
- StringToIntResult *stringToInt(const char *string) {
- StringToIntResult *result = safemalloc(sizeof(StringToIntResult));
- if (!string) {
- *result = (StringToIntResult){0, "Passed NULL."};
- return result;
- }
- if (string[0] == '\0') {
- *result = (StringToIntResult){0, "Invalid string."};
- return result;
- }
- bool startsWithNegativeSign = (string[0] == '-');
- if (startsWithNegativeSign) {
- string = string + 1;
- }
- uint64_t maxInt = abs64(startsWithNegativeSign ? INT64_MIN : INT64_MAX);
- uint8_t maxDigitNumber = snprintf( // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
- NULL, 0, "%" PRIu64, maxInt);
- size_t stringLength = strlen(string);
- if (stringLength == 0 || string[0] == '0' || stringLength > maxDigitNumber) {
- *result = (StringToIntResult){0, "Invalid string."};
- return result;
- }
- for (uint32_t i = 0; i < stringLength; ++i) {
- if (string[i] < '0' || string[i] > '9') {
- *result = (StringToIntResult){0, "The string contains non numerical characters."};
- return result;
- }
- }
- if (stringLength == maxDigitNumber) {
- char *maxString = safemalloc(maxDigitNumber + 1);
- (void)snprintf(maxString, // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
- maxDigitNumber + 1, "%" PRIu64, maxInt);
- for (uint32_t i = 0; i < stringLength; ++i) {
- if (string[i] > maxString[i]) {
- free(maxString);
- *result = (StringToIntResult){0, "The resulting integer is too large."};
- return result;
- }
- }
- free(maxString);
- }
- int64_t integer = strtoll(string, NULL, 10);
- if (startsWithNegativeSign) {
- integer = -integer;
- }
- *result = (StringToIntResult){integer, NULL};
- return result;
- }
- typedef struct {
- uint32_t previousElement;
- uint32_t nextElement;
- } Result;
- Result findNeighbouringElements(uint32_t element) {
- uint32_t fibs[] = {1, 1};
- uint32_t fib = 0;
- while (fibs[1] != element) {
- fib = fibs[0];
- fibs[0] = fibs[1];
- fibs[1] += fib;
- }
- return (Result){fibs[0], fibs[0] += fibs[1]};
- }
- int main() {
- printf("Enter a Fibonacci sequence member >>> ");
- char *inputString = input(9);
- if (!inputString) {
- puts("Invalid input.");
- return 1;
- }
- StringToIntResult *stringToIntResult = stringToInt(inputString);
- free(inputString);
- if (stringToIntResult->error) {
- puts(stringToIntResult->error);
- free(stringToIntResult);
- return 1;
- }
- Result result = findNeighbouringElements(stringToIntResult->integer);
- free(stringToIntResult);
- printf("Previous element: %" PRIu32 " Next element: %" PRIu32, result.previousElement, result.nextElement);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement