繁体   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