• 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

VPS Starter Arubacloud
0 głosów
671 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 (195,220 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 (195,220 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,250 wizyt
0 głosów
0 odpowiedzi 1,790 wizyt
pytanie zadane 14 września 2020 w Python przez urbix01 Gaduła (3,290 p.)

92,980 zapytań

141,943 odpowiedzi

321,189 komentarzy

62,309 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.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...