problem z wyswietlaniem tablicy lancuchow znakowych C

0

Zadanie

Wejście

Na standardowym wejściu program otrzymuje w pierwszej linii liczbę n dzieleń, które trzeba wykonać. W kolejnym wierszu znajduje się liczba d cyfr po przecinku, które mają być policzone. W kolejnych wierszach znajdują się oddzielone spacją pary liczb całkowitych p i q — dzielnych i dzielników.

1<=n<=1000
0<=d<=100000
0<=p<=100000000
1<=q<=100000000
Wyjście

Program ma wypisać na standardowym wyjściu w n wierszach odpowiednio zaokrąglone wyniki kolejnych dzieleń. Część całkowita wyniku oddzielona jest od reszty przecinkiem. Jeżeli d jest równe zero, to przecinek nie jest w ogóle wypisywany.

Przykład

Wejście

3
3
1 3
247 2000
259998 20000
Wyjście

0,333
0,124
13,000
Wymagania

Ilość używanej przez program pamięci nie powinna zależeć od danych wejściowych (złożoność pamięciowa stała). Program powinien działać w czasie proporcjonalnym do zadanej liczby miejsc po przecinku (złożoność czasowa liniowa).

moj program

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*======================================
  FUNKCJA DZIELI NA ZASADZIE DZIELENIA
			PISEMNEGO
======================================*/

char* dzielenie (int p, int q, int liczbaMiejscPoprzecinku)
{

	char cCzescUlamkowa[10003]; // 10000 miejsc po przecinku + ',' + znak konca tablicy + jedno na ew zaokraglenie
	char cCzescCalkowita[10];
	char cWynik[10012]; //czesc ulamkowa + max 9 z calkowitej


	int liczba1= (int)(p/q);
	int liczba2;
	int pomoc;

	itoa(liczba1, cCzescCalkowita,10);
	if (liczbaMiejscPoprzecinku>0)
	{
		cCzescUlamkowa[0]=',';
		liczba2=liczba1*q;
		liczba1=p;


		for(int i=1;i<=liczbaMiejscPoprzecinku+1;i++) //+1 bo przecinek a chcemy jedna wiecej zeby zaokraglac
		{
			pomoc=liczba1-liczba2;
			liczba1=pomoc*10;
			pomoc=(int)(liczba1/q);
			liczba2=pomoc*q;
			cCzescUlamkowa[i]=pomoc+48; //ASCII
		}


		/*======================================
					 ZAOKRAGLANIE
		======================================*/

		if(cCzescUlamkowa[liczbaMiejscPoprzecinku+1]>='5') //ostatnia cyfra
		{
			int k=0;
			int przeniesienie=1;
			if(cCzescUlamkowa[liczbaMiejscPoprzecinku-k]=='9') // przedprzedostatnia cyfra
			{
				while((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]=='9')&&(k<=liczbaMiejscPoprzecinku)&&(przeniesienie==1))
				{
					cCzescUlamkowa[liczbaMiejscPoprzecinku-k]='0';
					k++;
					przeniesienie=1;
					if((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]<'9')&&(cCzescUlamkowa[liczbaMiejscPoprzecinku-k]!=','))
					{
						przeniesienie=0;
						cCzescUlamkowa[liczbaMiejscPoprzecinku-k]+=1;
					}

					if((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]==',')&&(przeniesienie==1))
					{
						/* ZAMIANA LICZBY CALKOWITEJ NA INTA
						   ZWIEKSZENIE WARTOSCI O 1
						   PONOWNA ZAMIANA NA STRINGA		*/

						przeniesienie=0;
						int calkowita=atoi(cCzescCalkowita); // string to int

						calkowita++;

						itoa(calkowita,cCzescCalkowita,10); //int to string

					}
				}
			}
			else cCzescUlamkowa[liczbaMiejscPoprzecinku]+=1; //przedostatnia cyfra
		}
		cCzescUlamkowa[liczbaMiejscPoprzecinku+1]='\0';

		strcat(cWynik,cCzescCalkowita);
		strcat(cWynik,cCzescUlamkowa);

	}
	return cWynik;
}

int main()
{

	int liczbaDzialan,liczbaMiejscPoprzecinku;
	int p,q;			// DZIELNA I DZIELNIK
	scanf("%d",&liczbaDzialan);
	scanf("%d",&liczbaMiejscPoprzecinku);
	char *tabWynikow[1000];



	for(int i=0;i<liczbaDzialan;i++)
	{
		scanf("%d %d", &p, &q);
		tabWynikow[i] = dzielenie(p,q,liczbaMiejscPoprzecinku);
	}
	for(int j=0;j<liczbaDzialan;j++)
	{
		printf("%s\n",tabWynikow[j]);

	}

	return 0;
}

ostrzezenie:
z2c.cpp: In function char* dzielenie(int, int, int)': z2c.cpp:18: warning: address of local variable cWynik' returned

moje wyjscie:
0,3330,12413,000
0,3330,12413,000
0,3330,12413,000

nie bardzo rozumiem gdzie lezy problem i jak go naprawic. na upartego moglbym rozdzielac te wyniki po przecinkach i liczby miejsc po przecinku ale nie o to chodzi... prosze o pomoc i z gory dziekuje.

edit:
zamiast cCzescUlamkowa[liczbaMiejscPoprzecinku+1]='\0'; mozna dac cCzescUlamkowa[liczbaMiejscPoprzecinku+1]='\n' ; i tylko raz wyswietlic tablice ale tez nie o to chodzi;p

0

zamiast skomplikowanej funkcji dzielenie nie wystarczy:

printf("%.3lf", (double)dzielna/dzielnik)

?
a poza tym ostrzeżenie masz dlatego, że zwracasz wskaźnik do zmiennej lokalnej, która przestaje istnieć gdy funkcja kończy działanie.

0

nie wystarczy bo funkcja ma liczyc z dokladnoscia do 100000 miejsc po przecinku (wlasnie sie kapnalem ze nie 10000;p) a takiego ciagu znakow nie przechowa Ci zaden typ zmiennej

0

http://ideone.com/1TcCE
cWynik powinno mieć pamięć deklarowaną dynamicznie i być zwalniana gdy już nie jest potrzebna. no i oczywiście gdy dopisujesz coś do stringa to wypadało by się upewnić, że na początku jest pusty a nie jakieś śmieci. właśnie dlatego wyście masz takie a nie inne...

0

dzieki dziala:) a mozesz mi to jeszcze jakos wyjasnic bo nie bardzo rozumiem.
skoro dopiero przy wyswietlaniu zwalniam tablice to czemu nastepne sie wyswietlaja? czy chodzi o to ze zwalniam dany index w tej tablicy?
i co daje dynamiczne zaalokowanie tablicy w funkcji?

i 76 linijka to po prostu alternatywa?

0

no wlasnie widze ze cos mi nie przechodzi;/
user image
to co moge jeszcze poprawic?
program wyglada tak na chwile obecna http://wklej.to/AyM5d

1

dobra wszystko przechodzi:) podsylam rozwiazanie:)

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*======================================
  FUNKCJA DZIELI NA ZASADZIE DZIELENIA
			PISEMNEGO
======================================*/

char* dzielenie (int p, int q, int liczbaMiejscPoprzecinku)
{

	char cCzescUlamkowa[100003]; // 100000 miejsc po przecinku + ',' + znak konca tablicy + jedno na ew zaokraglenie
	char cCzescCalkowita[10]; //9 + znak konca
	char *cWynik = (char*)malloc(sizeof(char)*100012); //czesc ulamkowa + max 9 z calkowitej
	cWynik[0]=0;

	int liczba1= (int)(p/q);
	int liczba2;
	int pomoc;


	if (liczbaMiejscPoprzecinku>0)
	{
		sprintf(cCzescCalkowita, "%d", liczba1);
		cCzescUlamkowa[0]=',';
		liczba2=liczba1*q;
		liczba1=p;

		int i;
		for(i=1;i<=liczbaMiejscPoprzecinku+1;i++) //+1 bo przecinek a chcemy jedna wiecej zeby zaokraglac
		{
			pomoc=liczba1-liczba2;
			liczba1=pomoc*10;
			pomoc=(int)(liczba1/q);
			liczba2=pomoc*q;
			cCzescUlamkowa[i]=pomoc+48; //ASCII
		}


		/*======================================
					 ZAOKRAGLANIE
		======================================*/

		if(cCzescUlamkowa[liczbaMiejscPoprzecinku+1]>='5') //ostatnia cyfra
		{
			int k=0;
			int przeniesienie=1;
			if(cCzescUlamkowa[liczbaMiejscPoprzecinku-k]=='9') // przedprzedostatnia cyfra
			{
				while((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]=='9')&&(k<=liczbaMiejscPoprzecinku)&&(przeniesienie==1))
				{
					cCzescUlamkowa[liczbaMiejscPoprzecinku-k]='0';
					k++;
					przeniesienie=1;
					if((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]<'9')&&(cCzescUlamkowa[liczbaMiejscPoprzecinku-k]!=','))
					{
						przeniesienie=0;
						cCzescUlamkowa[liczbaMiejscPoprzecinku-k]+=1;
					}

					if((cCzescUlamkowa[liczbaMiejscPoprzecinku-k]==',')&&(przeniesienie==1))
					{
						/* ZAMIANA LICZBY CALKOWITEJ NA INTA
						   ZWIEKSZENIE WARTOSCI O 1
						   PONOWNA ZAMIANA NA STRINGA		*/

						przeniesienie=0;
						int calkowita=atoi(cCzescCalkowita); // string to int

						calkowita++;

						sprintf(cCzescCalkowita, "%d", calkowita); //int to string

					}
				}
			}
			else cCzescUlamkowa[liczbaMiejscPoprzecinku]+=1; //przedostatnia cyfra
		}
		cCzescUlamkowa[liczbaMiejscPoprzecinku+1]='\0';

		strcat(cWynik,cCzescCalkowita);
		strcat(cWynik,cCzescUlamkowa);

	}
	else
	{
		double temp=(double)p/(double)q;
		if ((temp-liczba1)>=0.5)
		{
			++liczba1;
		}
		sprintf(cCzescCalkowita, "%d", liczba1);

		strcat(cWynik,cCzescCalkowita);
	}
	return cWynik;
}

int main()
{

	int liczbaDzialan,liczbaMiejscPoprzecinku;
	int tab[1000][2];			// DZIELNA I DZIELNIK
	scanf("%d",&liczbaDzialan);
	scanf("%d",&liczbaMiejscPoprzecinku);
	char *tabWynikow;
	int i,j;


	for(i=0;i<liczbaDzialan;i++)
	{
		scanf("%d %d", &tab[i][0], &tab[i][1]);

	}
	for(j=0;j<liczbaDzialan;j++)
	{
		tabWynikow = dzielenie(tab[j][0],tab[j][1],liczbaMiejscPoprzecinku);
		printf("%s\n",tabWynikow);
		free(tabWynikow);

	}

	return 0;
}

user image

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