• 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)

VPS Starter Arubacloud
+1 głos
451 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 (251,210 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 (251,210 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ź 271 wizyt
pytanie zadane 12 maja 2019 w C i C++ przez Aleksandra01 Użytkownik (530 p.)
0 głosów
5 odpowiedzi 5,021 wizyt
0 głosów
1 odpowiedź 2,010 wizyt
pytanie zadane 26 listopada 2017 w C i C++ przez Karol.99 Użytkownik (550 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...