簡體   English   中英

如何在輸入長度未知的情況下讀取以逗號分隔的數字?

[英]How to read numbers separated by commas where the input is of unknown length?

我對問題的輸入必須如下所示:3,5,9,6,2,8。 我無法知道序列將有多少個元素,因此數組應該是動態的。

我嘗試使用 getchar 讀取每個數字,然后在將元素添加到數組中時重新分配 memory 但 getchar 一次僅讀取一位數字的 ASCII 值,因此如果我輸入 11,12-它將讀取 1 1 1 2 . 它也只將第一個 1 存儲到數組中。

int main(int argc, char *argv[]) {
    int initialSize = 100;
    int intCount = 0;                      
    int *sequence = safeMalloc(initialSize);
    char c = getchar();

    // reads first DNA sequence dynamically
    while (c != '\n') {
        if(c==',')
        {
            c=getchar();
        }
        printf("%d\n",c);
        if (intCount < initialSize) {
            sequence[intCount] = c-'0';
            intCount++;
            c = getchar();
        } else {
            initialSize = initialSize * 2;
            sequence = realloc((char*) sequence, sizeof(char*) * initialSize);
            sequence[intCount] = c-'0';
        }
    }
    for(int i=0;i<strlen(sequence);i++)
    {
        printf("%d\n", sequence[i]);
    }
} // EDIT: Adrian added this as it was clearly just a 'typo' to omit it.

我減去 0 的 ASCII 值以獲得實際數字,但是當我需要讀取整數時,它一次只讀取一個數字(例如:11 而不是 1,1)。 只要我不知道輸入有多大,有沒有辦法在不使用 getchar 的情況下讀取輸入。

如果數據只是整數:

while(isdigit(c = getchar())) {
    sequence[intCount] = 10 * sequence[intCount] + c-'0';
} 

否則,使用getdelim讀取一個值並用strtod解析它

請注意,這需要一些額外的邏輯來正確處理 EOF(具有多個while/getchar循環通常是不好的做法,因為它使該邏輯比必要的更復雜),但是由於您的原始代碼在多個地方調用getchar並且沒有似乎根本沒有檢查 EOF,無論如何你都需要重構。 上面的循環給出了總體思路。

下面是一些演示 getdelim 使用的代碼。 這讀取雙精度,並允許輸入以逗號或換行符分隔。

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

/* Use getdelim to read comma-separated numbers */

struct data {
        size_t idx;
        size_t siz;
        double *val;
};

FILE * xfopen(const char *, const char *);
void Realloc(struct data *);
void push(struct data *, double);
int print(const struct data *);

int
main(int argc, char **argv)
{
        ssize_t rc;
        struct data V = {0};
        size_t bufsiz = 0;
        char *buf = NULL;
        FILE *ifp = argc > 1 ? xfopen(argv[1], "r") : stdin;

        Realloc(&V);

        while( (rc = getdelim( &buf, &bufsiz, ',', ifp)) > 0) {
                char *end;
                push(&V, strtod(buf, &end));
                if(*end == '\n' && end[1]) {
                        push(&V, strtod(end, &end));
                }
                if( end == buf || strcspn(end, ",\n") ) {
                        fputs("invalid input\n", stderr);
                        exit(EXIT_FAILURE);
                }
        }
        return print(&V);
}

FILE *
xfopen(const char *path, const char *mode)
{
        FILE *fp = fopen(path, mode);
        if( fp == NULL ) {
                perror(path);
                exit(EXIT_FAILURE);
        }
        return fp;
}

void
Realloc(struct data *V)
{
        V->siz = V->siz ? V->siz * 2 : 1024;
        V->val = realloc( V->val, V->siz * sizeof *V->val );
        if( V->val == NULL) { perror("realloc"); exit(EXIT_FAILURE); }
        return;
}

void
push(struct data *V, double val)
{
        V->val[V->idx++] = val;
        if(V->idx == V->siz) {
                Realloc(V);
        }
}
int
print(const struct data *V)
{
        size_t i;
        for(i=0; i < V->idx; i++ ) {
                if(printf("%zu: %lg\n", i + 1, V->val[i]) < 0) {
                        return EXIT_FAILURE;
                }
        }
        return EXIT_SUCCESS;
}

我遇到過類似的東西,所以我沒有通過您的代碼中的錯誤來 go 。

因為我們不知道輸入的長度,所以要巧妙地做兩件事 1) 讀取輸入 2) 解析它並將輸入轉換為整數,以防萬一 strtok() 多於一位

我只使用 getchar() 完成了它,以下是程序的樣子,檢查它是否有幫助並且可以改進。

#include<stdlib.h>
#include<string.h>
int main()
{

char *input=NULL;
char *tmp=NULL, *brk;
char *sep=",";
char ch;
int i=0;
int total=0;
int SIZE = 80; /* mostly line ends with 80 chars */
int *numbers=NULL;

input=malloc(SIZE*sizeof(char));
if(input == NULL) {
   /* Failed to allocate memroy */
   return 1;
}
/* ----------- read input ----- */
do {
     ch=getchar();
     input[i]=ch;
     i++;
     if(ch == ','){
        total++;
     }
     if(i>=SIZE) {
        input=realloc(input, sizeof(char)*(SIZE+i));
        if (input == NULL) {
            break; /* failed to allocate memory */
        }
     }

} while (ch !='\n');

printf("Total input numbers %d\n", ++total);
numbers=malloc(total*sizeof(int));
if (numbers == NULL) {
    /* Fail */
    return 1;
}
i=0;
/* ------ parse and convert strings to integers ------- */
for(tmp=strtok_r(input, sep, &brk);
    tmp;
    tmp=strtok_r(NULL, sep, &brk)){
    numbers[i]=atol(tmp);
    i++;

}
printf("The numbers are\n");
for(i=0;i<total;i++){
    printf("%d\n", numbers[i]);
}
 return 0;
}

暫無
暫無

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

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