Hoe te controleren of een string een getal is?

Ik wil controleren of een tekenreeks een nummer is met deze code. Ik moet controleren of alle tekens in de string geheel getal zijn, maar de while retourneert altijd ISDIGIT = 1. Ik weet niet waarom dat als niet werkt.

char tmp[16];
scanf("%s", tmp);
int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
  if(tmp[j] > 57 && tmp[j] < 48)
    isDigit = 0;
  else
    isDigit = 1;
  j++;
}

Antwoord 1, Autoriteit 100%

Vergeet ASCII-codecontroles, gebruik isDigitof isnumber(zie man isnumber). De eerste functie controleert of het personage 0-9 is, de tweede accepteert ook verschillende andere getalkarakters, afhankelijk van de huidige locale.

Er kunnen zelfs betere functies zijn om de cheque te doen – de belangrijke les is dat dit A & NBSP is; beetje complexer dan het lijkt, omdat de precieze definitie van een “cijferoord” afhankelijk is van de specifieke locale en de tekenreekscodering.


Antwoord 2, Autoriteit 24%

 if(tmp[j] >= '0' && tmp[j] <= '9') // should do the trick

Antwoord 3, Autoriteit 17%

Meer voor de hand liggend en eenvoudig, draad veilig voorbeeld:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
    if (argc < 2){
        printf ("Dont' forget to pass arguments!\n");
        return(-1);
    }
    printf ("You have executed the program : %s\n", argv[0]);
    for(int i = 1; i < argc; i++){
        if(strcmp(argv[i],"--some_definite_parameter") == 0){
            printf("You have passed some definite parameter as an argument. And it is \"%s\".\n",argv[i]);
        }
        else if(strspn(argv[i], "0123456789") == strlen(argv[i])) {
            size_t big_digit = 0;
            sscanf(argv[i], "%zu%*c",&big_digit);
            printf("Your %d'nd argument contains only digits, and it is a number \"%zu\".\n",i,big_digit);
        }
        else if(strspn(argv[i], "0123456789abcdefghijklmnopqrstuvwxyz./") == strlen(argv[i]))
        {
            printf("%s - this string might contain digits, small letters and path symbols. It could be used for passing a file name or a path, for example.\n",argv[i]);
        }
        else if(strspn(argv[i], "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == strlen(argv[i]))
        {
            printf("The string \"%s\" contains only capital letters.\n",argv[i]);
        }
    }
}

Antwoord 4, autoriteit 7%

if ( strlen(str) == strlen( itoa(atoi(str)) ) ) {
    //its an integer
}

Omdat atoi tekenreeksen omzet in cijfers waarbij andere letters dan cijfers worden overgeslagen, moet de lengte van de tekenreeks gelijk zijn aan die van het origineel als er geen andere zijn dan cijfers.
Deze oplossing is beter dan innumber() als de controle op integer is.


Antwoord 5, autoriteit 5%

Ik moet hetzelfde doen voor een project waar ik momenteel aan werk. Hier is hoe ik dingen heb opgelost:

/* Prompt user for input */
printf("Enter a number: ");
/* Read user input */
char input[255]; //Of course, you can choose a different input size
fgets(input, sizeof(input), stdin);
/* Strip trailing newline */
size_t ln = strlen(input) - 1;
if( input[ln] == '\n' ) input[ln] = '\0';
/* Ensure that input is a number */
for( size_t i = 0; i < ln; i++){
    if( !isdigit(input[i]) ){
        fprintf(stderr, "%c is not a number. Try again.\n", input[i]);
        getInput(); //Assuming this is the name of the function you are using
        return;
    }
}

Antwoord 6, autoriteit 5%

In dit deel van je code:

if(tmp[j] > 57 && tmp[j] < 48)
  isDigit = 0;
else
  isDigit = 1;

Uw if-voorwaarde is altijd onwaar, waardoor isDigitaltijd wordt ingesteld op 1. Je wilt waarschijnlijk:

if(tmp[j] > '9' || tmp[j] < '0')
  isDigit = 0;
else
  isDigit = 1;

Maar. dit kan worden vereenvoudigd tot:

isDigit = isdigit(tmp[j]);

De logica van je lus lijkt echter een beetje misleidend:

int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
  isDigit = isdigit(tmp[j]);
  j++;
}

Omdat tmpgeen constante is, is het onzeker of de compiler de lengteberekening uit elke iteratie zal optimaliseren.

Zoals @andlrc in een opmerking suggereert, kun je in plaats daarvan gewoon op cijfers controleren, aangezien de afsluitende NUL de controle sowieso niet doorstaat.

while (isdigit(tmp[j])) ++j;

Antwoord 7, autoriteit 2%

#include <stdio.h>
#include <string.h>
char isNumber(char *text)
{
    int j;
    j = strlen(text);
    while(j--)
    {
        if(text[j] > 47 && text[j] < 58)
            continue;
        return 0;
    }
    return 1;
}
int main(){
    char tmp[16];
    scanf("%s", tmp);
    if(isNumber(tmp))
        return printf("is a number\n");
    return printf("is not a number\n");
}

Je kunt ook de stringfied-waarde controleren, wat ook zou kunnen werken met niet-Ascii

char isNumber(char *text)
{
    int j;
    j = strlen(text);
    while(j--)
    {
        if(text[j] >= '0' && text[j] <= '9')
            continue;
        return 0;
    }
    return 1;
}

Antwoord 8

Uw conditie zegt if X is greater than 57 AND smaller than 48. Xkan niet tegelijkertijd groter dan 57 en kleiner dan 48 zijn.

if(tmp[j] > 57 && tmp[j] < 48)

Het moet if X is greater than 57 OR smaller than 48:

if(tmp[j] > 57 || tmp[j] < 48) 

Antwoord 9

herschrijf de hele functie zoals hieronder:

bool IsValidNumber(char * string)
{
   for(int i = 0; i < strlen( string ); i ++)
   {
      //ASCII value of 0 = 48, 9 = 57. So if value is outside of numeric range then fail
      //Checking for negative sign "-" could be added: ASCII value 45.
      if (string[i] < 48 || string[i] > 57)
         return FALSE;
   }
   return TRUE;
}

Antwoord 10

Het probleem is dat het resultaat van uw code “isDigit” alleen de test met het laatste cijfer weergeeft. Voor zover ik je vraag begrijp, wil je isDigit = 0 retourneren wanneer je een teken hebt dat geen getal in je string is. Volgens uw logica zou u het als volgt moeten coderen:

char tmp[16];
scanf("%s", tmp);
int isDigit = 0;
int j=0;
isDigit = 1;  /* Initialised it here */
while(j<strlen(tmp) && isDigit == 0){
  if(tmp[j] > 57 || tmp[j] < 48) /* changed it to OR || */
    isDigit = 0;
  j++;
}

Om een meer begrijpelijke code te krijgen, zou ik ook de test wijzigen:

if(tmp[j] > 57 || tmp[j] < 48) 

naar het volgende:

if(tmp[j] > '9' || tmp[j] < '0')

Other episodes