Zapis danych z pliku do dynamicznej tablicy [Problem]

0

Witam,

W ramach ćwiczenia, wymyśliłem sobie zadanie, które będzie poległo na wczytaniu danych z pliku do dynamicznej tablicy, przemnożenie przez 2 i zapisanie w nowym pliku.
Po napisaniu programu, różnych testach i kombinacjach, program zapisuje w pliku jakieś śmieci... Czy ktoś mógłby mi podszepnąć w czym jest problem?

// tablice_pliki.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>


int _tmain(int argc, _TCHAR* argv[])
{
	FILE *read = fopen("dane.txt", "r");
	double *Vector;
	int count = 0;
	double helpVar;

	if(read)
	{
		printf("Dane zostaly wczytane pomyslnie!\n\n");

		while(!feof(read))
		{
			fscanf(read, "%lf", &helpVar);
			++count;
		}

		Vector = (double*) malloc (count*sizeof(double));

		for(int i=0; i<count; ++i)
		{
			fscanf(read, "%lf", &Vector[i]);
			Vector[i]*=2;
		}

		fclose(read);

		FILE *save = fopen("rozwiazanie.txt", "w");

		if(save)
		{
			
			for(int i=0; i<count; ++i)
			{
				fprintf(save, "[%d] = %.2lf \n", i+1, Vector[i]);
			}

			printf("Dane zostaly zapisane w pliku!\n");
			fclose(save);
		}
		else
			printf("Nie udalo sie zapisac danych!");


	}
	else
		printf("Nie udalo sie wczytac danych z pliku!");
	_getch();
	return 0;
}

PS. Wiem, że ta pomocnicza zmienna, jest bez sensu, jednak gdy zrobiłem sam licznik, to pętla kręciła się w nieskończoność, więc zorientowałem się, że musi ona coś wczytywać, żeby wiedzieć kiedy ma się zatrzymać, jednak, gdzie ma zapisać dane skoro nie wiem ile pamięci zaalokować?

Dziękuję za odpowiedzi,
Pozdrawiam

1

W momencie, gdy przeczytasz już cały plik (czyli gdy ta Twoja pętlą z pomocniczą zmienną się zakończy), dalsze fscanfy się nie powiodą, w związku z czym do Vector[i] masz wczytywane bzdury.
Musisz wykonać fseek na początek pliku przed jego ponownym skanowaniem.

Btw, nie potrzebujesz w ogóle liczyć wierszy. Po prostu jednocześnie wczytuj i zapisuj do drugiego pliku.

0

@Patryk27:

Dziękuję za szybką odpowiedź :) Masz rację, nie pomyślałem o tym. Dziękuję za podpowiedź.

Pozdrawiam

0

@Patryk27:

Mam jeszcze pytanie, czy jest możliwość aby uniknąć tej pierwszej pętli gdzie wczytywane są dane do pomocniczej zmiennej? Wspomniałeś, że można by wczytywać dane od razu do drugiego pliku, to prawda. A co w przypadku, gdy np chciałbym obliczyć średnią z tych danych i wypisać ją w konsoli? Czy sposób, według którego postępowałem jest dobry, czy może istnieje jakaś alternatywa? Bo wydaje mi się, że wczytywanie danych do pomocniczych zmiennych tylko po to aby "zliczyć dane" jest bez sensu :p

Pozdrawiam

1

Nie obsługujesz wyniku zwracanego z funkcji fscanf - popraw to.
http://www.cplusplus.com/reference/cstdio/fscanf/

Jak obliczyć średnią bez alokacji dynamicznej:
http://stackoverflow.com/questions/21216528/how-to-read-numbers-from-file-and-calculate-the-mean

0

@vpiotr:

Wybacz, ale nie bardzo rozumiem co masz na myśli "Nie obsługujesz wyniku zwracanego z funkcji fscanf - popraw to."

1
wyebani napisał(a):

@vpiotr:

Wybacz, ale nie bardzo rozumiem co masz na myśli "Nie obsługujesz wyniku zwracanego z funkcji fscanf - popraw to."

Wersja bez obsługi wyniku:

        while(!feof(read))
        {
            fscanf(read, "%lf", &helpVar);
            ++count;
        }

Wersja z obsługą:

        while(!feof(read))
        {
            if (fscanf(read, "%lf", &helpVar) != 1) {
               break;
            }
            ++count;
        }

Kiedy to się przyda?
Kiedy plik będzie uszkodzony (np. przy kopiowaniu lub po ręcznej edycji).

0

@vpiotr:
Czyli gdy nie uda się wczytać danej pętla zostanie przerwana, dobrze rozumiem?

1
wyebani napisał(a):

@vpiotr:
Czyli gdy nie uda się wczytać danej pętla zostanie przerwana, dobrze rozumiem?

Tak. Zwykle nie uda się gdy:

  • plik jest za krótki (tzn. jego długość mod sizeof(double) != 0)
  • właśnie padł dysk (i mimo że nie ma końca pliku nie dało się już nic przeczytać)
  • ktoś wyjął pendrive'a z portu USB w trakcie czytania
    itd...

Możesz tę obsługę podrasować - i w przypadku za krótkiego pliku przyjąć, że w ogóle plik jest ogólnie słaby i nic z niego nie akceptować (pokazać komunikat, wyzerować liczbę liczb, zrobić break lub ustawić jakąś flagę errorInFile na 1).

0

@vpiotr:
Okej, dziękuję za odpowiedzi! Dopiero zacząłem swoją przygodę z językiem C i ogólnie z programowaniem, wiąże się to z moimi studiami. Właśnie we wtorek mam laboratorium z programowania, które będzie oparte na operacjach plikowych i te informacje na pewno mi się przydają :)

Jeszcze raz dziękuje,
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1