[VS C++] problem z fgets()


(Przemekbaranowski) #1

W swojej klasie umieściłem następującą metodę:

bool data_generator_2::Core::load_names(void)

{

	char *temp;

    char *line;

	int i;

	this->l_imion_m = 0;

	this->l_imion_m = 0;

	int k = 0;

	temp = (char*)malloc(this->s_word1 * sizeof(char));

	line = (char*)malloc(this->s_word3 * sizeof(char));

	FILE *plik;

	fopen_s(&plik,"source/imiona.csv","r");


	while(feof(plik)==0)

	{

	   if(fgets(line,99,plik)!=0)return false; <-########################################## tu zawsze zwraca FALSE


		i = 0;

		while(line[i+2]!='\n')

		{

			temp[i] = line[i+2];

			i++;

		}//while

        temp[i] = 0;


		switch(line[0])

		{

		case 77:

			{

				strcpy_s(imiona_m[this->l_imion_m],strlen(imiona_m[this->l_imion_m]),temp);

				this->l_imion_m++;

				break;

			}//M

		case 75:

			{

				strcpy_s(imiona_k[this->l_imion_k],strlen(imiona_m[this->l_imion_m]),temp);

				this->l_imion_k++;

				break;

			}//K

		}//switch

	}//while

	fclose(plik);

	free(temp);

	free(line);

	return true;

}//load_names

Jest to metoda klasy zarządzanej (ref)

Za każdym razem wywolanie tej metody kończy się na FGETS - za każdym razem zwraca błąd

Dlaczego?????


(dobryteddy) #2

Może to głupio zabrzmi,ale próbowałeś dać nawiasy ?, tzn:

if(fgets(line,99,plik)!=0) { return false; }


(Przemekbaranowski) #3

jeżeli po instrukcji warunkowej IF jest tylko jedna instrukcja, to nie trzeba dawać klamer, ale nie w tym rzecz. jak zostawie nawet samo fgets (bez ifa) to program się zwyczajnie zawiesza


(dobryteddy) #4

A może w pętli "while" użyj:

fgets(line,99,plik)!=0

zamiast tego FEOF ?


(Przemekbaranowski) #5

nie w tym rzez - wykrzacza przecież na fgets, po tym jak wejdzie do pętli.


(Sawyer47) #6

Nie wgłębiałem się jak ten kod działa, ale na pewno poważnym błędem jest wychodzenie z funkcji przed flclose i free. Powinieneś raczej robić break z tej pętli, a return powinno być ostatnią instrukcją.


(dobryteddy) #7

Znalazłem coś takiego: "If you don't read before the while(!feof(f)) then it is broken since the EOF flag does not get set until after a read has been done"

Jeszcze jeden pomysł :slight_smile:

fgets(line,99,plik)==0

(Blapiter) #8
if (plik == NULL) 

{

perror ("bład otwarcia pliku");

return false;

}


while(! feof(plik) && fgets(line,99,plik)) // gdy różny od końca pliku, następnie "coś" wczytał.

{

[...]

}

([alex]) #9

blapiter , to beż sensu, wystarczy:

while(fgets(line,this->s_word3,plik)) // this->s_word3 - na tyle przydzielono line.  {   [...]  }[/code]

A zamiast tego:
[code=php]= 0;line[i+2]!='\n')

(Blapiter) #10

alex Bez sensu to to nie jest

while(! feof(plik) && fgets(line,99,plik))

jedynie można uznać to za nadmierna ostrożność, poza tym chciałem pokazać Przebar-owi jak używać "bool-o" zwracanych funkcji w pętlach :slight_smile:


(Przemekbaranowski) #11

eureka! (prawie)

zmieniłem troszkę kod, na taki:

bool data_generator_2::Core::load_names(void)

{

	char *temp;

    char *line;

	int i,j;

	char c;

	this->l_imion_m = 0;

	this->l_imion_m = 0;

	int k = 0;

	temp = (char*)malloc(30 * sizeof(char));

	line = (char*)malloc(100 * sizeof(char));

	char imiona_mm[1000][30];

	char imiona_kk[1000][30];

	//char line[100];

	FILE *plik;

	fopen_s(&plik,"source/imiona.csv","r");

	while(feof(plik)==0)

	{

	  // if(fgets(line,99,plik)!=0)return false;


	   fread(&c,sizeof(char),1,plik);

	   j=0;

	   while(c!='\n' && c!=0)

	   {

			line[j] = c;

			fread(&c,sizeof(char),1,plik);

			j++;

	   }

	   line[j] = 0;


		i = 0;

		while(line[i+2]!=0)

		{

			temp[i] = line[i+2];

			i++;

		}//while

        temp[i] = 0;


		switch(line[0])

		{

		case 77:

			{

				//strcpy_s(imiona_m[this->l_imion_m],strlen(imiona_m[this->l_imion_m]),temp);

				strcpy(imiona_mm[this->l_imion_m],temp);

				this->l_imion_m++;

				break;

			}//M

		case 75:

			{

				//strcpy_s(imiona_k[this->l_imion_k],strlen(imiona_m[this->l_imion_k]),temp);

				strcpy(imiona_kk[this->l_imion_k],temp);

				this->l_imion_k++;

				break;

			}//K

		}//switch

	}//while

	fclose(plik);

	free(temp);

	free(line);

	return true;

}//load_names

wrzucam teraz dane do tablicy deklarowanej statycznie, a nie alokowanej poprzez malloc(), z mallockiem program się wykrzaczał.

stad następne pytanie: jak powinno alokować się i zwalniać pamięć w VS C++ ??

bo malloc() raczej się nie sprawdza;/