2010-11-07 5 views
0

Я читаю:Преобразование набора символов в целое из файла

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

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

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

+2

Предпочитают 'isdigit (ch)' для идентификации цифр. –

+0

О, это хороший совет, спасибо. – Qosmo

ответ

0

Моя идея состоит в том, чтобы читать в каждом 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

О, не знал, что sscanf может это сделать. Это превалирует над атои? – Qosmo

+0

@Queops: Не знаю, какой из них предпочитают гуру и педанты. Обычно я использую 'sscanf', поскольку он намного более общий, и может обрабатывать/извлекать значения, встроенные в посторонние символы, и получать сразу несколько строк из одной и той же строки, используя строку формата. – MAK

+0

atoi не обрабатывает ошибки. sscanf делает некоторые из них (возможно, вы должны проверить возвращаемое значение). но единственная функция, которая обнаруживает переполнение (т. е. обнаруживает, что число, подобное 9999999999999999999999999999999999999999, не может соответствовать длине или длине, является функцией strtol/strtoll, а также имеет возможность получить указатель на первый нецифровой символ поэтому вы можете обнаружить суффиксы. – BatchyX

0

Предполагая, что ваша картина типа 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

Должен сказать, что шаблона вообще нет. – Qosmo

0

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

#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 
Смежные вопросы