Cara untuk mengkonversi string ke integer dalam C?

Saya mencoba untuk mencari tahu apakah ada alternatif cara untuk mengkonversi string ke integer dalam C.

Saya secara teratur pola berikut dalam kode saya.

char s[] = "45";

int num = atoi(s);

Jadi, apakah ada cara yang lebih baik atau cara lain?

Mengomentari pertanyaan (6)
Larutan

Ada strtol yang lebih baik IMO. Juga saya telah mengambil keinginan di strtonum, jadi gunakan ini jika anda memiliki itu (tapi ingat itu's tidak portable):

long long
     strtonum(const char *nptr, long long minval, long long maxval,
     const char **errstr);

EDIT

Anda juga mungkin tertarik dalam strtoumax dan strtoimax yang merupakan fungsi standar di C99. Misalnya anda bisa mengatakan:

uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
    /* Could not convert. */

Pokoknya, tinggal jauh dari atoi:

panggilan atoi(str) harus setara dengan:

(int) strtol(str, (char **)NULL, 10)

kecuali bahwa penanganan kesalahan yang mungkin berbeda. Jika nilai tidak dapat diwakili, perilaku yang tidak terdefinisi.

Komentar (7)

Don't menggunakan fungsi dari ato... kelompok. Ini yang rusak dan hampir tidak berguna. Cukup solusi yang lebih baik akan menggunakan sscanf, meskipun tidak sempurna.

Untuk mengkonversi string ke integer, fungsi dari strto... kelompok harus digunakan. Dalam kasus tertentu anda akan strtol fungsi.

Komentar (3)

Kuat C89 strtolberbasis solusi

Dengan:

  • tidak terdefinisi perilaku (seperti bisa memiliki dengan atoi keluarga)
  • yang lebih ketat definisi dari bilangan bulat dari strtol (misalnya tidak ada ruang kosong atau trailing sampah karakter)
  • klasifikasi kesalahan kasus (misalnya untuk memberikan pesan kesalahan berguna untuk pengguna)
  • "testsuite"
#include 
#include 
#include 
#include 
#include 
#include 

typedef enum {
    STR2INT_SUCCESS,
    STR2INT_OVERFLOW,
    STR2INT_UNDERFLOW,
    STR2INT_INCONVERTIBLE
} str2int_errno;

/* Convert string s to int out.
 *
 * @param[out] out The converted int. Cannot be NULL.
 *
 * @param[in] s Input string to be converted.
 *
 *     The format is the same as strtol,
 *     except that the following are inconvertible:
 *
 *     - empty string
 *     - leading whitespace
 *     - any trailing characters that are not part of the number
 *
 *     Cannot be NULL.
 *
 * @param[in] base Base to interpret string in. Same range as strtol (2 to 36).
 *
 * @return Indicates if the operation succeeded, or why it failed.
 */
str2int_errno str2int(int *out, char *s, int base) {
    char *end;
    if (s[0] == '\0' || isspace(s[0]))
        return STR2INT_INCONVERTIBLE;
    errno = 0;
    long l = strtol(s, &end, base);
    /* Both checks are needed because INT_MAX == LONG_MAX is possible. */
    if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
        return STR2INT_OVERFLOW;
    if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
        return STR2INT_UNDERFLOW;
    if (*end != '\0')
        return STR2INT_INCONVERTIBLE;
    *out = l;
    return STR2INT_SUCCESS;
}

int main(void) {
    int i;
    /* Lazy to calculate this size properly. */
    char s[256];

    /* Simple case. */
    assert(str2int(&i, "11", 10) == STR2INT_SUCCESS);
    assert(i == 11);

    /* Negative number . */
    assert(str2int(&i, "-11", 10) == STR2INT_SUCCESS);
    assert(i == -11);

    /* Different base. */
    assert(str2int(&i, "11", 16) == STR2INT_SUCCESS);
    assert(i == 17);

    /* 0 */
    assert(str2int(&i, "0", 10) == STR2INT_SUCCESS);
    assert(i == 0);

    /* INT_MAX. */
    sprintf(s, "%d", INT_MAX);
    assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
    assert(i == INT_MAX);

    /* INT_MIN. */
    sprintf(s, "%d", INT_MIN);
    assert(str2int(&i, s, 10) == STR2INT_SUCCESS);
    assert(i == INT_MIN);

    /* Leading and trailing space. */
    assert(str2int(&i, " 1", 10) == STR2INT_INCONVERTIBLE);
    assert(str2int(&i, "1 ", 10) == STR2INT_INCONVERTIBLE);

    /* Trash characters. */
    assert(str2int(&i, "a10", 10) == STR2INT_INCONVERTIBLE);
    assert(str2int(&i, "10a", 10) == STR2INT_INCONVERTIBLE);

    /* int overflow.
     *
     * `if` needed to avoid undefined behaviour
     * on `INT_MAX + 1` if INT_MAX == LONG_MAX.
     */
    if (INT_MAX < LONG_MAX) {
        sprintf(s, "%ld", (long int)INT_MAX + 1L);
        assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);
    }

    /* int underflow */
    if (LONG_MIN < INT_MIN) {
        sprintf(s, "%ld", (long int)INT_MIN - 1L);
        assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);
    }

    /* long overflow */
    sprintf(s, "%ld0", LONG_MAX);
    assert(str2int(&i, s, 10) == STR2INT_OVERFLOW);

    /* long underflow */
    sprintf(s, "%ld0", LONG_MIN);
    assert(str2int(&i, s, 10) == STR2INT_UNDERFLOW);

    return EXIT_SUCCESS;
}

GitHub upstream.

Berdasarkan pada: https://stackoverflow.com/a/6154614/895245

Komentar (8)

Anda dapat kode sedikit atoi() untuk memulai:


int my_getnbr(char *str)
{
  int result;
  int puiss;

  result = 0;
  puiss = 1;
  while (('-' == (*str)) || ((*str) == '+'))
  {
      if (*str == '-')
        puiss = puiss * -1;
      str++;
  }
  while ((*str >= '0') && (*str 
Komentar (4)

Hanya ingin berbagi solusi untuk unsigned long juga.

unsigned long ToUInt(char* str)
{
    unsigned long mult = 1;
    unsigned long re = 0;
    int len = strlen(str);
    for(int i = len -1 ; i >= 0 ; i--)
    {
        re = re + ((int)str[i] -48)*mult;
        mult = mult*10;
    }
    return re;
}
Komentar (4)

Anda selalu dapat memutar anda sendiri!


#include 
#include 
#include 

int my_atoi(const char* snum)
{
    int idx, strIdx = 0, accum = 0, numIsNeg = 0;
    const unsigned int NUMLEN = (int)strlen(snum);

    /* Check if negative number and flag it. */
    if(snum[0] == 0x2d)
        numIsNeg = 1;

    for(idx = NUMLEN - 1; idx >= 0; idx--)
    {
        /* Only process numbers from 0 through 9. */
        if(snum[strIdx] >= 0x30 && snum[strIdx] 
Komentar (11)

Fungsi ini akan membantu anda


int strtoint_n(char* str, int n)
{
    int sign = 1;
    int place = 1;
    int ret = 0;

    int i;
    for (i = n-1; i >= 0; i--, place *= 10)
    {
        int c = str[i];
        switch (c)
        {
            case '-':
                if (i == 0) sign = -1;
                else return -1;
                break;
            default:
                if (c >= '0' && c 
Komentar (2)

Ok, saya punya masalah yang sama.Saya datang dengan solusi ini.Ini bekerja untuk saya yang terbaik.Aku mencoba atoi() tetapi tidak't bekerja dengan baik bagi saya.Jadi di sini adalah solusi saya:

void splitInput(int arr[], int sizeArr, char num[])
{
    for(int i = 0; i < sizeArr; i++)
        // We are subtracting 48 because the numbers in ASCII starts at 48.
        arr[i] = (int)num[i] - 48;
}
Komentar (0)
//I think this way we could go :
int my_atoi(const char* snum)
{
 int nInt(0);
 int index(0);
 while(snum[index])
 {
    if(!nInt)
        nInt= ( (int) snum[index]) - 48;
    else
    {
        nInt = (nInt *= 10) + ((int) snum[index] - 48);
    }
    index++;
 }
 return(nInt);
}

int main()
{
    printf("Returned number is: %d\n", my_atoi("676987"));
    return 0;
}
Komentar (1)

Dalam C++, anda dapat menggunakan fungsi seperti:

template 
T to(const std::string & s)
{
    std::istringstream stm(s);
    T result;
    stm >> result;

    if(stm.tellg() != s.size())
        throw error;

    return result;
}

Hal ini dapat membantu anda untuk mengkonversi string ke tipe seperti float, int, double...

Komentar (1)

Ya, anda dapat menyimpan bilangan bulat secara langsung:

int num = 45;

Jika anda harus mengurai string, atoi atau strol akan memenangkan "terpendek jumlah kode" kontes.

Komentar (2)