簡體   English   中英

將十六進制數字轉換為十進制數字

[英]Convert hexadecimal numbers to decimal numbers

我有一個文本文件,其中一行用空格分隔數字,如以下示例所示:

1 -2 3.1 0xf 0xcc

使用C程序解析文件后,結果應保存在向量中,其內部結構應為:

V[0]=1
V[1]=-2
V[2]=3.1
V[3]=15
V[4]=204

基本上我需要將以0x開頭的數字轉換為十進制數字。

我試過將所有元素存儲在char向量中,然后將它們轉換為數字,但沒有成功。

對於使用C語言編寫的任何幫助將不勝感激。

您需要的是整數類型的strtol函數。 您可以使用endptr遍歷字符串。 對於double ,可以使用atof函數,但是必須首先檢查字符串是否包含點。

編輯:作為user3386109提到strtoddouble的更好的解決方案。

假設您在數組中包含字符串:

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

int main()
{
    char numbers_str[] = "1 -2 3.1 0xf 0xcc";
    int ints[10];
    double doubles[10];
    int ints_idx = 0, doubles_idx = 0;

    const char delims[] = " ";
    char *it = strtok(numbers_str, delims);
    while(it != NULL)
    {
        char *dot_it = strchr(it, '.');
        // When a dot is found then a double number is found
        if(dot_it)
            doubles[doubles_idx++] = strtod(it, NULL);
        // When a dot is not found then we've got an integer
        else
            ints[ints_idx++] = strtol(it, NULL, 0);
        it = strtok(NULL, delims);
    }

    printf("Integers found: \n");
    for(int i = 0; i < ints_idx; ++i)
        printf("%d\n", ints[i]);

    printf("Double numbers found: \n");
    for(int i = 0; i < doubles_idx; ++i)
        printf("%f\n", doubles[i]);
}

您可以看看 sscanf 這是一個准程序。 我相信您可以從這里接載:

#include  <stdio.h>

int main(void)
{
    char *hex = "0xF";
    int i= 0;
    sscanf(hex, "%x", &i);
    printf("%d", i);
}

處理從行中讀取值的最簡單方法是使用strtod在行中向下移動。 strtod兩個指針作為參數。 第一個指向起點以搜索數字(或前導+/- ),以便將數字的字符串表示形式轉換為數值(跳過所有前導空格)。 第二個指針到指針( endptr )將設置為轉換中使用的最后一個字符之后的下一個字符。 您開始搜索要從那里轉換的下一個數字(例如,設置p = ep;然后重復該過程)。

您可以查閱手冊頁以獲取更多詳細信息,但是要驗證轉換是否成功,請檢查指針是否等於結束指針(意味着數字已轉換),並檢查以確保未設置errno 如果沒有轉換數字(意味着您有一個無效字符),您只想手動向前掃描該行,直到找到下一個+/-0-9 (或者您按了以n結尾的字符)。

您想通過保持簡單的計數器並在數組已滿時退出循環來保護數組邊界並限制嘗試存儲在向量數組中的值的數量。

這是一個簡短的示例(省略了NAN和INF檢查):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define VECSZ 5   /* if you need a constant, define one (or more) */

int main (int argc, char **argv) {

    int i, n = 0;
    double v[VECSZ] = {0.0};
    char buf[BUFSIZ] = "";
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (n < VECSZ && fgets (buf, BUFSIZ, fp)) { /* read each line */
        char *p = buf, *ep;     /* pointer, end-pointer for strtod  */
        while (n < VECSZ) {     /* convert vales in buf until VECSZ */
            double tmp = strtod (p, &ep);
            if (p != ep) {                  /* digits converted  */
                if (!errno)                 /* validate no error */
                    v[n++] = tmp;           /* add to vector  */
                p = ep;                     /* update pointer */
            }
            else {  /* no digits converted */
                fprintf (stderr, "error: no digits converted.\n");
                /* scan forward to next valid '+,-,0-9' */
                while (*p && *p != '-' && *p != '+' && (*p < '1' || '9' < *p))
                    p++;
                if (*p)         /* numbers remain in line */
                    continue;
                break;          /* otherwise get next line */
            }
        }
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    for (i = 0; i < n; i++)
        printf ("v[%d]=% g\n", i, v[i]);

    return 0;
}

輸入文件示例

$ cat dat/strtod_vect.txt
1 -2 3.1 0xf 0xcc

使用/輸出示例

$ ./bin/strtod_vect dat/strtod_vect.txt
v[0]= 1
v[1]=-2
v[2]= 3.1
v[3]= 15
v[4]= 204

仔細檢查一下,如果您還有其他問題,請告訴我。 您可以檢查strtod(3)-Linux手冊頁以獲取更多詳細信息和可以進行的錯誤檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM