Jump to content

char *pointeri, masīvi un printf, rekursīvā funkcijā


Recommended Posts

Vingrinājuma programma, kurā rekursīva funkcija stringā nomaina visus "pi" uz "3.14"
ar komentāriem kodā atzīmētas jautājumu vietas:
1. Kā ir labāk , iekopēt temp stringā vienu char un atgriezt temp, vai atgriezt pointeri uz pirmo elementu, vai vēl kāds labāks risinājums kad funkcijai ir jāatgriež viens char?
2. un 3. Kāpēc nestrādā temp atgriešana ( neizprintējas pēdējais "3.14", kad printē st2), bet sāk strādāt kad pašā funkcijā pirms temp atgriešanas tiek izsaukts printf  temp?
4. Kāpēc neizvadās pareizi stringi ja visus mēģina izvadīt uz reiz bet izvadās pareizi, ja katru izvada atsevišķi?
 

// uzdevums no http://codingbat.com/java/Recursion-1

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

char *changePi(char *string)
{
	char temp[256] = "";

	if(strlen(string) == 0)
		return "\0";

	 if(strlen(string) == 1)
	 {
		 //1. kaa ir labaak

		 //strncpy(temp, string, 1);
		 //return temp;
		 return &string[0];
	 }

	if(strlen(string) == 2)
	{
		if(string[0] == 'p' && string[1] == 'i')
		{
			/* 2 .kaapeec nestraadaa?
			strcpy(temp,"3.14");

			//kaapeec saak straadaat kad pieliek sho?
			//printf("temp is %s\n", temp);

			return temp;
			*/

			/* 3 kaapeec nestraadaa?
			temp[0] = '3';
			temp[1] = '.';
			temp[2] = '1';
			temp[3] = '4';
			temp[4] = '\0';

			//kaapeec saak straadaat kad pieliek sho?
			//printf("temp is %s\n", temp);

			return temp;
			*/

			//ar sho straadaa
			return "3.14";
		}
		else
			return strncpy(temp, string, 2);
	}
	else
	{
		if(string[0] == 'p' && string[1] == 'i')
		{
			strcpy(temp,"3.14");
			return strcat(temp, changePi(string +2));
		}
		else
		{
			strncpy(temp, string, 1);
			return strcat(temp, changePi(string +1));
		}
	}
}

int main (void)
{
	char st1[] = "a", st2[] = "pi what is pi", st3[] = "";

	/* 4 kaapeec nestraadaa 
	printf("original string - modified string\n%s - %s\n%s - %s\n%s - %s\n",
			st1, changePi(st1),st2, changePi(st2), st3, changePi(st3));
	*/

	printf("original string - modified string\n%s - %s\n", st1, changePi(st1));
	printf("%s - %s\n", st2, changePi(st2));
	printf("%s - %s\n", st3, changePi(st3));

	getchar();

	return 0;
}
Link to post
Share on other sites

char *changePi(char *string){

    char temp[256] = ""; //šie dati funkcijas beigās "pazūd".

    return strcat(temp, changePi(string +1)); //šeit funkcija atgriež pointeri uz datiem, kas funkcijas beigās "pazūd"

}

Viens risinājums ir izdalīt atmiņu dinamiski:

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

 

Šeit aprakstīts tavs gadījums un sniegts viens risinājums kā darīt.

http://stackoverflow.com/questions/14416759/return-char-string-from-a-function

Edited by Salmo
Link to post
Share on other sites

ja kodē iekš C, tad ir jāizprot, kuri mainīgie tiek izvietoti stekā  (kas "iet bojā" pēc f-jas return)   

Link to post
Share on other sites

Paldies par palīdzību, sapratu kļūdu, palasīju par stack un heap un uzrakstīju šo funkciju šādi:

 

Vai pareizi saprotu, ka būs vairākas reizes izveidoti neatkarīgi pointeri *out, katrs savā rekursīvajā izsaukšanas reizē savādāks, un aizņemtais atmiņas daudzums būs visu *out summa, kura tiks atbrīvota tikai tad, kad aiztaisīs programmu. Vai tomēr ir iespēja to atbrīvot bez programmas aizvēršanas, ja nu gadījumā būtu nepieciešams?

#define MAX_STRING_SIZE 256

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

char *changePi(char *string)
{
	char temp[MAX_STRING_SIZE], *out;

	int stringSize;

	out = ( char *) malloc ( 5 * sizeof (char) );

	out[0] = '\0';
	out[1] = '\0';

	if(strlen(string) == 0)
		return out;

	 if(strlen(string) == 1)
	 {
		 out[0] = string[0];
		 return out;
	 }

	if(strlen(string) == 2)
	{
		if(string[0] == 'p' && string[1] == 'i')
			return strcpy(out, "3.14");
		else
			return strncpy(out, string, 2);
	}
	else
	{
		if(string[0] == 'p' && string[1] == 'i')
		{
			strcpy(out,"3.14");
			strcpy(temp, changePi(string +2));
			stringSize = (strlen(temp) + 5) * sizeof (char);
			out = ( char *) realloc (out, stringSize);
			return strcat(out, temp);
		}
		else
		{
			strncpy(out, string, 1);
			strcpy(temp, changePi(string +1));
			stringSize = (strlen(temp) + 2) * sizeof (char);
			out = ( char *) realloc (out, stringSize);
			return strcat(out, temp);
		}
	}
}

int main (void)
{
	char st1[] = "", st2[] = "a", st3[] = "pi what is pi";

	printf("original string - modified string\n%s - %s\n%s - %s\n%s - %s\n",
			st1, changePi(st1),st2, changePi(st2), st3, changePi(st3));
	
	getchar();

	return 0;
}
Link to post
Share on other sites

Vai strtok() spēj kā vienu delimiteru pieņemt "pi" ? Pēc maniem eksperimentiem iznāk ka viņš ņem divus atsevišķus delimiterus 'p' un 'i', ja ievada "pi" ka delimitera parametru.

Link to post
Share on other sites

Nē, bet tu iebaro strtok lielo stringu un tokenu, un pēc tam velc ārā pa vārdam. Tas, ko tev vajag, ir kā tokenu lietot tukšumu, jebšu ' '. Un tad rekursīvā funkcija velk no strtok() ārā kamēr kautkas nāk ārā un konkrētos stringus no sākuma salīdzini pēc garuma strlen. Ja garums atbilst tad varēsi salīdzināt pa burtam. Protamistiski, ir arī strcmp(). 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...