web-dev-qa-db-fra.com

Comment convertir une chaîne en int64_t?

Comment convertir un paramètre de programme de argv à int64_t? atoi() ne convient que pour les entiers 32 bits.

16
pmichna

Une tentative conforme à C99.

[edit] employé @R. correction

// Note: Typical values of SCNd64 include "lld" and "ld".
#include <inttypes.h>
#include <stdio.h>

int64_t S64(const char *s) {
  int64_t i;
  char c ;
  int scanned = sscanf(s, "%" SCNd64 "%c", &i, &c);
  if (scanned == 1) return i;
  if (scanned > 1) {
    // TBD about extra data found
    return i;
    }
  // TBD failed to scan;  
  return 0;  
}

int main(int argc, char *argv[]) {
  if (argc > 1) {
    int64_t i = S64(argv[1]);
    printf("%" SCNd64 "\n", i);
  }
  return 0;
}
11
chux

Il y a plusieurs façons de le faire:

  strtoll(str, NULL, 10);

Ceci est conforme à POSIX C99.

vous pouvez également utiliser strtoimax; qui a le prototype suivant:

 strtoimax(const char *str, char **endptr, int base);

C'est bien parce que cela fonctionnera toujours avec l'intmax_t local ... C'est C99 et vous devez inclure <inttypes.h>

9
Ahmed Masud

Faire ce portable à 100% est un peu délicat. long long doit avoir au moins 64 bits, mais ne doit pas nécessairement être un complément de deux. Il ne sera donc peut-être pas en mesure de représenter -0x7fffffffffffffff-1. Par conséquent, l'utilisation de strtoll pourrait avoir un casse d'angle cassée. Le même problème s'applique à strtoimax. Ce que vous pouvez faire à la place est de consommer de l’espace de début (si vous voulez autoriser l’espacement) et de rechercher d’abord le signe, puis d’utiliser strtoull ou strtoumax, l’un ou l’autre étant requis pour la prise en charge de valeurs allant jusqu’à la plage entière de int64_t. Vous pouvez ensuite appliquer le signe:

unsigned long long x = strtoull(s, 0, 0);
if (x > INT64_MAX || ...) goto error;
int64_t y = negative ? -(x-1)-1 : x;

Cette logique est écrite pour éviter tous les cas de débordement.

2
R..

strtoll le convertit en un long long qui est généralement un int de 64 bits.

2
Kninnug

Cela a fonctionné pour moi avec un autre type int64, et j'aime bien le style propre C++:

std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;

Vous pouvez obtenir une erreur de compilation: operartor << ... n'est pas défini.

Et je ne sais pas ce qui se passe si argv [i] contient "HALLO".

1
Fritz Pom

Les utilisateurs issus d'une recherche sur le Web doivent également considérer std::stoll .

Il ne répond pas strictement à cette question initiale de manière efficace pour un const char* mais de nombreux utilisateurs auront un std::string de toute façon. Si vous ne vous souciez pas de l'efficacité, vous devriez obtenir une conversion implicite (basée sur la conversion définie par l'utilisateur à l'aide du constructeur à un seul argument std::string) en std::string même si vous avez un const char*.

C'est plus simple que std::strtoll qui nécessitera toujours 3 arguments.

Il devrait jeter si l’entrée n’est pas un nombre, mais voir ces commentaires .

0
davidvandebunte