• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wczytanie liczb z pliku do tablicy. (C)

Object Storage Arubacloud
+1 głos
456 wizyt
pytanie zadane 9 stycznia 2022 w C i C++ przez Sway22 Początkujący (270 p.)
Witam, jestem bardzo początkująca w programowaniu i mam takie pytanie: Jak wczytać liczby z pliku do tablicy w C?
komentarz 9 stycznia 2022 przez Sway22 Początkujący (270 p.)
int main()
{
    FILE *tablica;
    tablica = fopen("C:\\Ciąg.txt", "r");

    int a[7]; // jak zrobić żeby program sam sczytywał ile wyrazów jest w pliku?
    int i;

    if (tablica == NULL){
        printf("Error Reading File\n");
        exit (0);    // co to robi?
    }

    for (i = 0; i < 7; i++){
        fscanf(tablica, "%d,", &a[i] );
    }

    for (i = 0; i < 7; i++){
        printf("%d" , i);
        printf("wyraz ciagu: %d \n", a[i]);
    }

    fclose(tablica);

 

komentarz 9 stycznia 2022 przez j23 Mędrzec (194,920 p.)

Funkcja realloc twoim przyjacielem ;)

komentarz 9 stycznia 2022 przez VBService Ekspert (252,520 p.)

@Sway22, 

if (tablica == NULL){
        printf("Error Reading File\n");
        exit (0);    // co to robi?
}

 

exit(0)

komentarz 9 stycznia 2022 przez Sway22 Początkujący (270 p.)
ale co to robi? po co to tam jest?
1
komentarz 9 stycznia 2022 przez VBService Ekspert (252,520 p.)

Jeżeli jest jakikolwiek problem z "otwarciem" pliku Ciąg.txt, exit(0) powoduje natychmiastowe zamknięcie programu.

1 odpowiedź

0 głosów
odpowiedź 10 stycznia 2022 przez Wojciech Rokicki Użytkownik (850 p.)
edycja 11 stycznia 2022 przez Wojciech Rokicki

Aby automatycznie wczytywać nieznany nam rozmiar danych należy wykorzystać wskaźniki i dynamiczne alokowanie pamięci. Poniższy kod jest poszukiwanym przez Ciebie rozwiązaniem:

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

int main(int argc, char *argv[]){
    FILE *fp;
    int32_t temp;
    int32_t *grades = NULL;
    int32_t count = 0;

    fp = fopen("grades.txt","r");

    while(fscanf(fp,"%d",&temp) != EOF) {
        count++;
        grades = realloc(grades,sizeof(*grades)*count);
        grades[count-1] = temp;
    }   

    temp = 0;

    while(temp < count) {
        printf("the read value is %d\r\n", grades[temp]);
        temp++;
    }

    fclose(fp);

    free(grades);
    grades = NULL;
}

Inspiracja dla powyższego kodu:
https://stackoverflow.com/a/19094299

W języku C++ jest gotowa struktura vector, która jest rodzajem tablicy o zmiennym rozmiarze. Mechanizmy zawarte w strukturze zapewniają  poprawne przydzielanie i zwalnianie pamięci, co ułatwia pracę programiście.

Innym, prostszym rozwiązaniem jest po prostu przyjęcie bardzo dużego rozmiaru tablicy do wczytania wszystkich wartości.

Funkcja exit odpowiada za zakończenie działania wywołującego ją procesu. Argumentem jest status z jakim proces kończy pracę - w tym przypadku 0, czyli bez błędu.

Tutaj więcej na temat różnicy pomiędzy funkcją return, a exit:
https://stackoverflow.com/questions/3463551/what-is-the-difference-between-exit-and-return

1
komentarz 10 stycznia 2022 przez j23 Mędrzec (194,920 p.)

To rozdzielenie na malloc i realloc jest zbędne, bo jak dasz tej drugiej wskaźnik null, to zachowa się jak ta pierwsza.

sizeof(grades)*count

Na 64-bitowych współczesnych platformach grades będzie miało 8 bajtów, bo to wskaźnik, a chcemy przecież count intów, czyli 32-bitowych wartości. Tu jest błąd.

1
komentarz 10 stycznia 2022 przez Oscar Nałogowiec (29,290 p.)
edycja 10 stycznia 2022 przez Oscar
Nawet pomijając ten błąd, zacytowany kod jest chaotyczny i mało edukacyjny. Nadmiar zmiennych (jedna liczy w dół a druga w górę, jedna o 1 więcej niż druga), while zamiast naturalnego w tej sytuacji for, plik otwarty do odczytu i zapisu, otwarcie w trybie binarnym a czytanie tekstowe, reallokowanie dla każdej pojedynczej danej itp.
komentarz 10 stycznia 2022 przez j23 Mędrzec (194,920 p.)

reallokowanie dla każdej pojedynczej danej itp.

To nie jest aż taki problem, bo realloc nie realokuje co każde wywołanie. Jak się dobrze wstrzeli, to może realokować dopiero po przekroczeniu (wielokrotności) wielkości strony pamięci.

komentarz 11 stycznia 2022 przez Wojciech Rokicki Użytkownik (850 p.)

@j23, Dzięki wielkie za merytoryczny komentarz. Poprawiłem kod i mam nadzieję, że teraz jest już prawidłowo. Jeśli masz jeszcze jakieś uwagi to z chęcią je przyjmę. Faktycznie alokowane było zbyt dużo pamięci, nieadekwatnie do zapotrzebowania.

1
komentarz 11 stycznia 2022 przez Wojciech Rokicki Użytkownik (850 p.)

@Oscar, Dzięki za komentarz. Faktycznie kod jest trochę chaotyczny... Usunąłem zmienną index - teraz używam count. Kod miał być w C, więc trzymałem się standardu ANSI C. Jeśli znasz jakiś wydajny/wygodny sposób na wczytywanie liczb z pliku z wykorzystaniem pętli for, to podziel się rozwiązaniem w komentarzu. Jeśli masz jeszcze jakieś uwagi, prosiłbym o ich udzielenie. Będę starać się o udoskonalenie tego fragmentu kodu do granic możliwości laugh

2
komentarz 11 stycznia 2022 przez j23 Mędrzec (194,920 p.)

@Wojciech Rokicki, w sumie zamieniłbym jeszcze wyrażenia w stylu *(grades+temp) na tradycyjne grades[temp]. Nie ma co komplikować zapisu, jeśli nic na tym nie zyskujesz.

komentarz 11 stycznia 2022 przez Wojciech Rokicki Użytkownik (850 p.)

Masz rację, dziękuję smiley

Podobne pytania

0 głosów
1 odpowiedź 277 wizyt
pytanie zadane 12 maja 2019 w C i C++ przez Aleksandra01 Użytkownik (530 p.)
0 głosów
5 odpowiedzi 5,073 wizyt
0 głosów
1 odpowiedź 2,042 wizyt
pytanie zadane 26 listopada 2017 w C i C++ przez Karol.99 Użytkownik (550 p.)

92,524 zapytań

141,357 odpowiedzi

319,382 komentarzy

61,914 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...