Почему мой printf () не печатает первый символ в текстовом файле? - PullRequest
0 голосов
/ 12 декабря 2018

Я программист Noob C.Я не могу прочитать все символы моего текстового файла.У моего file.txt есть числа: 9,2,3,4,5,6, но когда я запускаю код, написанный ниже, он просто пропускает 9 и печатает остальные числа.Однако, когда я ставлю пробел перед 9, он работает отлично.Как мне это исправить?и почему это происходит?

FILE* fp;
fp = fopen("file.txt", "r");
int a[10];
char ch;

while((ch=getc(fp))!= EOF)
{
    fscanf(fp, "%d", &a[ch]);
    printf("%d ", a[ch]);
}

Заранее спасибо;

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Неясно, сколько int в вашем файле, и текущий способ их хранения подвержен ошибкам.fgetc возвращает int, который либо EOF (-1), либо 0-255, поэтому ch должен был быть объявлен int, а затем, когда (ch=getc(fp))!= EOF равно true, ch будет содержать 0-255.В следующем fscanf(fp, "%d", &a[ch]); вы снова читаете из файла, но в массив в позиции индекса ch, что явно не является вашим намерением (и, вероятно, также произойдет сбой при чтении символа со значением> 9. Подсказка: «0» имеет значение 48).Приведенное ниже решение может показаться слишком сложным, но я привык к C ++, где все это происходит под капотом, и вам не нужно об этом беспокоиться.Возможно, вы получите некоторые идеи, назвав это.

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

/* dynamic memory storage - start */
typedef struct {
    size_t m_size;
    size_t m_reserved;
    int* m_data;
} store;

/* create a store */
store* store_create() {
    store* s = malloc(sizeof(store));
    if(s) {
        /* initialize values */
        s->m_size = 0;
        s->m_reserved = 1; /* a very conservative start value */
        s->m_data = malloc(sizeof(int)*s->m_reserved);
        if(s->m_data==NULL) {
            free(s);
            s = NULL;
        }
    }
    return s;
}

/* destroy a store */
void store_destroy(store* s) {
    /* free the integer array */
    free(s->m_data);
    /* free the store struct */
    free(s);
}

bool store_reserve(store* s, size_t new_res) {
    /* reserve more space for the int's if needed */
    if(new_res>s->m_reserved) {
        int* n = realloc(s->m_data, sizeof(int)*new_res);
        if(n==NULL) return false; /* could not expand storage */
        s->m_reserved = new_res;
        s->m_data = n;
    }
    return true;
}

// check if it's time to increase reserved storage
bool store_check_reserve(store* s) {
    if(s->m_size == s->m_reserved)
        /* change 5/4 to a larger value for more aggressive
         * increase of memory allocation */
        return store_reserve(s, (s->m_reserved+1)*5/4);
    else
        return true;
}

// add a value to the store
bool store_add(store* s, int v) {
    if(!store_check_reserve(s)) return false;

    s->m_data[s->m_size++] = v;
    return true;
}

/* dynamic memory storage - end */

int main(int argc, char* argv[]) {
    FILE* fp;
    fp = fopen("file.txt", "r");

    /* create a store for our unknown amount of int's */
    store* myStore = store_create();

    /* scan for strings separated by comma and newline
     * and allocate memory for it */
    char* str;
    while(fscanf(fp, " %m[^,\n],", &str)==1)
    {
        int num;
        /* convert string to integer */
        if(sscanf(str, "%d", &num)==1) {
            /* store the extracted value */
            if(store_add(myStore, num)==false) {
                fprintf(stderr, "FAILED STORING %d\n", num);
            }
        }
        // free string allocated by fscanf (%m) */
        free(str);
    }
    fclose(fp);

    printf("All %d stored values:\n", myStore->m_size);
    for(size_t i=0; i<myStore->m_size; ++i) {
        printf("%d = %d\n", i, myStore->m_data[i]);
    }

    /* release memory allocated by our store */
    store_destroy(myStore);
    return 0;
}
0 голосов
/ 12 декабря 2018

Функция getc в while((ch=getc(fp))!= EOF) потребляет один символ из файла;если 9 является первым символом в вашем файле, он будет просто прочитан в ch и - поскольку ваш набор символов, вероятно, будет ASCII - установит ch==0x39.

Итак (1)9 больше не будет доступен для fscanf(fp, "%d", &a[ch]);;вот почему вы думаете, что это «пропущено».

(2) запись в a в позиции ch затем превышает границы массива a.

...