开发者

Convert a set of chars to int from a file

I'm reading:

22:5412:99:00 (...)

From a text file using (ch=fgetc(fp)) != EOF because I don't have only those numbers to read. Identifying a number is easy with if(ch >= 48 && ch <= 57) but the thing is I want to put those numbers 22, 5412 into an array of integers. However when I read a char it reads part of number since each number is char. It gets 2 (and not 22 like I want to) and in the next iterati开发者_StackOverflowon reads the other 2. How can I save each set of numbers into it's own integer?

I hope I was clear enough, thanks!


My idea is to read in each char, and if it is a digit append it to a buffer. Whenever we get a non-digit, we just read the contents of the buffer as a string using sscanf, and clear the buffer for the next value.

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

int read_buffer(char* buffer, int* sz)
{
    int ret;
    if (*sz==0) return 0;
    buffer[*sz]='\0'; //end the string
    sscanf(buffer,"%d", &ret); //read the contents into an int
    *sz=0; // clear the buffer
    return ret;
}

int main()
{
    char buffer[1000];
    int sz=0;
    char ch;
    FILE* input=fopen("input.txt","r");
    // "input.txt" contains 22:5412:99:00
    while ((ch=fgetc(input))!=EOF)
    {
        int number;
        if (isdigit(ch))
        {
            buffer[sz++]=ch; // append to buffer
        }
        else
        {
            printf("Got %d\n",read_buffer(buffer,&sz)); // read contents of buffer and clear it
        }
    }
    if (sz) // check if EOF occured while we were reading a number
        printf("Got %d\n",read_buffer(buffer,&sz)); 
    fclose(input);
    return 0;
}


You would need to store the numbers as a string or a char* and use atoi to actually convert it to a number. http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/


Assuming your pattern is of the type NN:NNNN:NN:NN, parse on the delimiter, feeding characters into a buffer:

int idx = 0, nIdx = 1;
int firstN, secondN, thirdN, fourthN;
char buf[5];
...
while ((ch=fgetc(fp)) != EOF) {
    if (ch != ':') {
        buf[idx++] = ch;
    } 
    else {
        buf[idx] = '\0';
        idx = 0;
        switch (nIdx++): {
            case 1: firstN = atoi(buf); break;
            case 2: secondN = atoi(buf); break;
            case 3: thirdN = atoi(buf); break;
        }
    }
}
buf[idx] = '\0';
fourthN = atoi(buf);
...


I did a full program out of the previous post -- and some testing :-)

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

/* fill `array` with at most `siz` values read from the stream `fp` */
/* return the number of elements read */
size_t fillarray(int *array, size_t siz, FILE *fp) {
  int ch;
  size_t curr = 0;
  int advance_index = 0;
  while ((ch = fgetc(fp)) != EOF) {
    if (isdigit((unsigned char)ch)) {
      array[curr] *= 10;
      array[curr] += ch - '0';
      advance_index = 1;
    } else {
      if (advance_index) {
        advance_index = 0;
        curr++;
        if (curr == siz) { /* array is full */
          break;
        }
      }
    }
  }
  return curr + advance_index;
}

int main(void) {
  int array[1000] = {0};
  int n, k;

  n = fillarray(array, 1000, stdin);
  if (n > 0) {
    printf("%d values read:\n", n);
    for (k=0; k<n; k++) {
      printf(" %d", array[k]);
    }
    puts("");
  } else {
    fprintf(stderr, "no data read\n");
  }
  return 0;
}

And a test run

$ ./a.out 
24555:76423 foobar 76235 jgfs(8) jhg x86-64 passw0rd RS232
[CTRL+D]
8 values read:
 24555 76423 76235 8 86 64 0 232
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜