1

(I am very new to both coding and C.)

I want to check if the nr one string in "string argv" is one or more decimals and if it is convert it to an integer. I think I may need to iterate over the string but so far this code is not working. It says segmentation fault.

This is my code:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

int main (int argc, string argv [])
{

    //check command line
    if (argc == 2)
    {
        printf("success");
    }
    else
    {
        printf("Usage: ./caesar key.");
    }

    //validate number
    if (isdigit (argv[1]))
    {
        int x = atoi(argv[1]);
        printf("I is now %i\n", x);
        return 0;
    }

    if (isalpha(argv[1]))
     {
        printf("Usage: ./caesar key\n");
        return 1;
    }
}
16
  • 1
    Which line generates the error and what is the exact error message text? Commented Jan 26, 2021 at 18:20
  • The condition array is bigger than two is not standard C. Use strlen() with the name of your array and compare the result with the number 2 by the mean of this binary operator: > Commented Jan 26, 2021 at 18:21
  • 1
    'some of it is in pseudocode, because that part works', well, you will need to do more to convince an experienced developer than just make a claim. Compiler error messages are often misleading and generate an error on a,line far removed from the real error location. Commented Jan 26, 2021 at 18:25
  • @MartinJames thanks for replying. I have changed it a bit and its compiling but it does not print out the value of the integer. I just get "segmentaton fault" Commented Jan 26, 2021 at 18:36
  • 1
    The function isdigit tests whether a single character is a digit. If you want to test whether all characters in a string are digits, you must loop over the string. The function atoi tries to convert the whole string to a number. (The loop is in the function itself.) There is another function, strtol, which converts a string to a long. It has better possibilities for error checking. Commented Jan 26, 2021 at 18:52

2 Answers 2

1

main function takes (int argc, char *argv[]) parameters. argv is a pointer to pointer and argv[1] is a pointer to a char array too. You should send a character to isdigit and isalpha, not a pointer. You get a segmentation fault because of this probably.

Sign up to request clarification or add additional context in comments.

Comments

1

check if ... string ... is one or more decimals and if it is convert it to an integer.

isdigit (argv[1]) --> argv[1] is a pointer to a string. isdigit(int ch) expects a single character, not a pointer. Enable all compiler warnings for fast feedback.


A direct approach uses strtol()

bool test_and_convert(const char *s, long *valptr) {
  errno = 0; // set to 0 to later detect overflow
  int base = 10;
  char *endptr;
  long *valptr = strtol(s, &endptr, base);
  if (s == endtpr) {
    return false; // No conversion
  }
  if (errno == ERANGE) {
    return true; /* or false, OP's choice here */
    // *valptr is clamped to LONG_MIN or LONG_MAX
  }

  // Detect trailing non-numeric text if desired
  if (*endptr) {
    return false;
  }

  return true;
}

A plodding approach akin to OP's.

bool test_and_convert_plodding(const char *s, int *valptr) {
  // Best to access characters as unsinged char for `is...()` functions.
  const unsigned char *us = (const unsigned char *) s; // 
  
  // Maybe skip leading spaces
  while (isspace(*us)) us++;

  unsigned char sign = *us;
  if (sign == '-' || sign == '+') {
    us++;
  }

  // Accumulate digits
  unsigned found = false;
  unsigned uvalue = 0;
  while (isdigit(*us)) {
    found = true;
    // Overflow detection code needed here is TBD
    uvalue = ulvaue*10 + (*us - '0');
  }

  if (!found) {
    return false; // No digits
  }

  // Maybe skip trailing spaces
  while (isspace(*us)) us++;

  // Maybe detect non-numeric junk at the end.
  if (*us) return false;
  
  // Overflow detection code needed here is TBD
  *valptr = (sign == '-'  && uvlaue > 0) ? (-(int)(uvalue - 1) - 1) : (int) uvalue;
  return true;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.