Конвертировать набор символов в int из файла - PullRequest
0 голосов
/ 07 ноября 2010

Я читаю:

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

Из текстового файла, используя (ch=fgetc(fp)) != EOF, потому что у меня нет только этих чисел для чтения.Определить число легко с помощью if(ch >= 48 && ch <= 57), но я хочу поместить эти числа 22, 5412 в массив целых чисел.Однако, когда я читаю символ, он читает часть числа, поскольку каждое число является символом.Он получает 2 (а не 22, как я хочу) и в следующей итерации читает остальные 2. Как я могу сохранить каждый набор чисел в свое целое число?

Надеюсь, я был достаточно ясен, спасибо!

Ответы [ 4 ]

0 голосов
/ 07 ноября 2010

Я сделал полную программу из предыдущего поста - и некоторые испытания: -)

#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;
}

и тестовый прогон

$ ./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 голосов
/ 07 ноября 2010

Моя идея состоит в том, чтобы прочитать в каждом char, и, если это цифра, добавить его в буфер. Всякий раз, когда мы получаем не цифру, мы просто читаем содержимое буфера как строку, используя sscanf, и очищаем буфер для следующего значения.

#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;
}
0 голосов
/ 07 ноября 2010

Предполагая, что ваш шаблон имеет тип NN:NNNN:NN:NN, выполните синтаксический анализ по разделителю и загрузите символы в буфер:

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);
...
0 голосов
/ 07 ноября 2010

Вам нужно будет хранить числа в виде строки или символа * и использовать atoi для фактического преобразования их в число.http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

...