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

Sumowanie liczb z danego pliku i zapisywanie ich do innego

Object Storage Arubacloud
0 głosów
544 wizyt
pytanie zadane 11 maja 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

Hej :)

Rozwiązuję takie oto zadanie:

Napisz program, który pobierze od użytkownika nazwę pliku źródłowego i docelowego a następnie, dla każdej linii z pliku źródłowego ma obliczy sumę liczb w niej zawartych. Uzyskane wyniki mają być zapisane do pliku docelowego, w osobnych liniach. Jeżeli w danej linii nie będzie żadnej liczby, program powinien ją pominąć.

Jeżeli podany przez użytkownika plik nie istnieje to program powinien wyświetlić komunikat Couldn't open file i zwrócić wartość kod błędu 4. W przypadku kiedy nie uda się utworzyć plik wyjściowego komunikat Couldn't create file i zakończyć działanie z kodem błędu 5.

Jeżeli w pliku nie będzie żadnych wartości liczbowych program powinien wyświetlić komunikat File corrupted i zakończyć działanie z kodem błędu 6.

Ostatecznie, jeżeli udało się wykonać wszystkie obliczenia program powinien wyświetlić na ekranie komunikat File saved i zakończyć pracę z kodem błędu 0.

Przykładowa interakcja z programem - sukces (dla pliku wejściowego text.txt, plik wyjściowy out.txt ):

Podaj sciezke do pliku:⏎
text.txt⏎
Podaj sciezke do pliku:⏎
out.txt⏎
File saved
Przykładowa interakcja z programem - błąd wejścia/wyjścia:

Podaj sciezke do pliku:⏎
lie.txt⏎
Couldn't open file⏎
Podaj sciezke do pliku:⏎
reach.txt⏎
Podaj sciezke do pliku:⏎
experience.bin⏎
Couldn't create file⏎
Uwaga

W programie nie wolno używać funkcji alokujacych pamięć.
W programie można zadeklarować tylko tablice na 30 znaków (do przechowywania nazw plików). Deklaracja musi wyglądać następująco: nazwa_zmiennej[31];.
W programie nie wolno używać operatora [].
W plikach mogą się znajdować również inne symbole oprócz liczb, symbole te mają być pominięte w trakcie przetwarzania danych z pliku.

Na tą chwilę rozpisałem swój kod:

#include <stdio.h>


int main()
{
    printf("Podaj sciezke do pliku:\n");
    char r_file[31];
    char w_file[31];
    scanf(" %30[^\n]",r_file);
    FILE * handle_read =fopen(r_file,"r");
    if( handle_read == NULL )
    {
        printf("Couldn't open file");
        return 4;
    }
    printf("Podaj sciezke do pliku:\n");
    scanf(" %30[^\n]",w_file);
    FILE * handle_write = fopen(w_file,"w");
    if( handle_write == NULL )
    {
        fclose(handle_read);
        printf("Couldn't create file");
        return 5;
    }
    int znak;
    int suma = 0;
    int i = 0;
    while( fscanf(handle_read,"%d",&znak) == 1 )
    {
        
            fprintf(handle_write,"%d\n",&suma);
            suma = 0;
        i++;
    }
    printf("\n%d\n",i);
    if( i == 0 )
    {
        printf("File corrupted");
        return 6;
    }
    printf("File saved");
    return 0;
}

Problem mam przy zliczaniu sumy dla poszczególnego wiersza. Liczby wczytuję za pomocą funkcji fscanf. Jak mogę sprawdzić, czy docieram do znaku końca linii ( '\n' )? Jeżeli już to sprawdzę, będę mógł zapisać sumę z danego wiersza do nowego pliku. Bardzo proszę o pomoc. 

1 odpowiedź

0 głosów
odpowiedź 11 maja 2020 przez j23 Mędrzec (194,920 p.)
edycja 12 maja 2020 przez j23

Coś w ten deseń:

    char c = 0;
    int acc = 0;

    do {
        while (c != '\n' && (c = fgetc(file)) != EOF && isspace(c));
        
        int v = 0;
        int minus = 1;
        
        if(c == '-') minus = -1, c = fgetc(file);

        while (isdigit(c)) {
            v *= 10;
            v += c - '0';
            c = fgetc(file);
        }
    
        v *= minus;
    
        acc += v;

        if (c == '\n') {
            c = fgetc(file);
            printf("%d\n", acc);
            acc = 0;
        }
    } while (c != EOF);

 

komentarz 11 maja 2020 przez Hubertius Bywalec (2,970 p.)

Całkiem spoko rozwiązanie ^^

Pierwsza pętla "wewnętrzna" jak rozumiem służy do konstruowania liczby. Druga ma natomiast sprawdzać, czy nie jest to znak biały (jeśli tak, to nie powinny być tutaj dodatkowe instrukcje do tej pętli)? 

Została jeszcze kwestia sprawdzania, czy liczba jest ujemna. Miałem pomysł, żeby za pomocą fseek-a cofać się o jeden bajt do tyłu z bieżącej pozycji i sprawdzać, czy znak pod tym bajtem to '-'. Potem powrót na starą pozycję i jeżeli poprzedni znak to był minus to w tym momencie przemnażałbym v przez -1. Jednak coś niepoprawnie wykonuję fseek-a. 

 do
    {
        int v = 0;
        while ((znak = fgetc(handle_read)) != EOF && isdigit(znak))
        {
            v *= 10;
            v += znak - '0';
        }
        if( isdigit(znak) != 0 )
        {
            fseek(handle_read,-1,SEEK_CUR);
            char temp;
            temp = fgetc(handle_read);
            fseek(handle_read,1,SEEK_CUR);
            if( temp == '-' )
            {
                //printf("Tutaj!");
               v = -v;
            }
        }
        suma += v;

        while (znak != '\n' && (znak = fgetc(handle_read)) != EOF && isspace(znak));

        if (znak == '\n')
        {
            fprintf(handle_write,"%d\n",suma);
            suma = 0;
        }

   }while (znak != EOF);

:/

komentarz 12 maja 2020 przez j23 Mędrzec (194,920 p.)

(jeśli tak, to nie powinny być tutaj dodatkowe instrukcje do tej pętli)? 

Po co? Pętla czyta do pierwszego niebiałego znaku, a to wszystko dzieje się w warunku pętli.

Miałem pomysł, żeby za pomocą fseek-a cofać się o jeden bajt do tyłu z bieżącej pozycji i sprawdzać

Słabo. Po co czytać coś, co już zostało przeczytane?


Poprawiłem kod, bo miał błąd, który dzisiaj zauważyłem.

Podobne pytania

0 głosów
2 odpowiedzi 1,207 wizyt
0 głosów
0 odpowiedzi 1,719 wizyt
pytanie zadane 14 września 2020 w Python przez urbix01 Gaduła (3,290 p.)

92,565 zapytań

141,416 odpowiedzi

319,598 komentarzy

61,948 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!

...