2016-03-16 82 views
1

所以我想存儲已經從鍵盤讀入整數的樣品C.用戶輸入數組int類型:閱讀整數從緩衝區到C中的數組

8 99 5 7 8 

變量聲明:

int k; 
int size; 
char buf[100]; 

上面是我的緩衝區和其他變量的數組。 以下是讀入緩衝區的整數。

printf("Please enter in the numbers for the array:\n"); 
fgets(buf, 100, stdin); 
buf[strlen(buf) - 1] = '\0'; 

size = (strlen(buf)/2)+1; 

int *array = (int *)malloc(sizeof(int)*size); 

因此,正確分配我的數組。

int i, j; 
for(i = 0, j = 0; i < size; i++, j = j+2) 
{ 
    array[i] = buf[j] - '0'; 
} 

上面的代碼實際工作,但不適合有雙位數的數字,僅低於10及以上的0號我如何解決我的代碼,使我在正確的整數讀? 我試圖做一個for循環與sscanf,但只是導致只有在所有元素中輸入的第一個整數數組。

+1

你可能想看看'strtol()'。 – EOF

+0

@EOF你的意思是'strtok()'? – MikeCAT

+1

注意:他們說[你不應該在C]中拋出'malloc()'的結果(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – MikeCAT

回答

-1
unsigned int len=0,tmp=0; 
char j,isnumber=0; 
for(char*i=buf;j=*i;i++) 
{ 
    if(j>='0'&&j<='9') 
    { 
     tmp=tmp*10+j-'0'; 
     isnumber=1; 
    } 
    else 
    { 
     if(isnumber) 
      array[len++]=tmp; 
     tmp=0; 
     isnumber=0; 
    } 
} 

而且,你不需要

buf[strlen(buf) - 1] = '\0'; 

size = (strlen(buf)/2)+1; 
+0

如何聲明(如果需要,還需要初始化)'array'? – MikeCAT

+0

'unsigned int array [50];' – v7d8dpo4

+0

空格不僅僅用於縮進。它們也大大提高了令牌之間的可讀性。而且 - 除非有充分理由不要 - 應該使用標準庫的功能。 – Olaf

1

如何解決我的代碼,使我在正確的整數讀?

使用strtol()解析字符串,如@EOF建議的那樣。它提供了一個結束指針。

long *array = malloc(sizeof *array * size); 
if (array == NULL) Handle_OutOfMemory(); 

char *p = buf; 
size_t i; 
for(i = 0; i<size; i++) { 
    // Cope with white space with nothing after it. 
    while (isspace((unsigned char) *p)) p++; 
    if (*p == '\0') break; 

    char *end; 
    errno = 0; 
    long num = strtol(p, &end, 10); 
    // If no conversion or out of range ... 
    if (p == end || errno) { 
    fprintf(stderr, "trouble converting `%s` into an integer.\n", p); 
    break; 
    } 
    array[i] = num; 
    p = end; 
} 

// Use array[0] ... array[i-1] 
1

您可以使用sscanfstrtol從輸入字符串中提取的數字。在兩種情況下,將給出三條信息從每個呼叫:

  • 的指示有效數字已發現數
  • 輸入陣列中的位置的
  • 的值,其中所述下一個號碼將被發現

sscanf,返回值表示成功或失敗。對於示例代碼中的sscanf(請參閱下文),成功的返回值爲1,其他都是失敗。如果成功,則該號碼的值被放置在指定的地址處,例如,示例代碼中的&temp

這裏是棘手的部分:您需要在數組中的位置開始搜索下一個數字。 sscanf有一個特殊的轉換,即%n轉換。 %n的輸出是執行轉換時消耗的字符數。

在下面的示例代碼中,我使用了一個指針ptr,該指針最初指向輸入字符串的開頭。在每次通過循環時,在sscanf中使用%n來更新變量n,其指示轉換當前編號消耗了多少字符。通過在for循環中將n添加到ptr,指針前進到下一個數字。

int *array = malloc(sizeof(int) * size); 
int n = 0; 
int i = 0; 
for (char *ptr = buf; *ptr; ptr += n) 
{ 
    int temp; 
    if (sscanf(ptr, "%d %n", &temp, &n) != 1) { 
     // error: not a number 
     break; 
    } 
    array[i++] = temp; 
} 

作爲評價提及@chux,加入空間格式字符串"%d %n"將消耗每個數後尾隨空白並相應地設置的n值。因此,如果輸入行僅包含數字,則當for語句檢測到*ptr已到達NUL終止符時,循環將結束。但是如果輸入包含非數字,則當sscanf失敗時,循環將爲break。這可以用於錯誤檢查。

+1

''%d%n「'有一個空格很好地消耗了像'\ n''這樣的尾部空白。有助於區分'ptr'是否按預期完成。 – chux

+1

謝謝@chux,這是一個很好的觀點。我已經更新了答案。 – user3386109

0

如果數字來自stdin,那麼將它們作爲字符串讀取並轉換它們比使標準庫爲您執行它更加費力。在這裏我硬編碼了100個整數的最大數目。循環後,i將代表array中有效整數的數量。

int array[100] = {0}; 
int i = 0; 

while (i < 100) 
{ 
    int input; 
    int scanresult = scanf("%d", &input); 

    if (scanresult == 1) 
    { 
     // 1 item was successfully scanned 
     array[i] = input; 
     i++; 
    } 
    else 
    { 
     // either EOF was reached or the input was not scannable as an integer 
    } 
}