تخصیص حافظه به رشته و ارسال به تابع؟

one hacker alon

New Member
با یاد خدا
سلام
من می خواستم از کاربر 2 رشته بگیرم بعد اونها رو به یه تابع ارسال کنم که اون 2 رشته کنار هم قرار بده یعنی ادغام کنه اگه از روش معمولی بخوام برم به صورت زیر در میاد اما می خوام این کار رو از طریق تخصیص حافظه پویا انجام بدم ( malloc() ) بخاطر اینکه من نمیدونم طول رشته کاربر چقدر هست دوستان اگه کسی میتونه راهنمایی کنه ممنون میشم راهنمایی کنید.( نحوه استفاده از تابع malloc رو میدونم اما بکارگیری اون رو به این شکل نمیدونم)

کد:
کد:
Char a[100],b[100]
Scanf("%s",a)
Scanf("%s",b)
F(a,b)
Void f(char a[100],char b[100])
Char h[]="hi"
Char c [210]
Strcat(c,h)
Strcat(c,a)
Strcat(c,b)
 

the_king

مدیرکل انجمن
با یاد خدا
سلام
من می خواستم از کاربر 2 رشته بگیرم بعد اونها رو به یه تابع ارسال کنم که اون 2 رشته کنار هم قرار بده یعنی ادغام کنه اگه از روش معمولی بخوام برم به صورت زیر در میاد اما می خوام این کار رو از طریق تخصیص حافظه پویا انجام بدم ( malloc() ) بخاطر اینکه من نمیدونم طول رشته کاربر چقدر هست دوستان اگه کسی میتونه راهنمایی کنه ممنون میشم راهنمایی کنید.( نحوه استفاده از تابع malloc رو میدونم اما بکارگیری اون رو به این شکل نمیدونم)
مشکل اصلی شما اینه که در هر متغیری که داخل یک تابع تعریف میشه موقع ورود به تابع ایجاد میشه و موقع خروج
از تابع نابود میشه، در نتیجه زمانی که از تابع خارج می شویم دیگه اون رشته که داخل تابع ایجاد شده وجود نداره.

دو روش برای حل این مشکل پیشنهاد می کنم.

روش اول - رشته خروجی به عنوان پارامتر سوم به تابع ارسال شود :
در این روش ما رشته c رو در خارج از تابع F تعریف می کنیم و مثل پارامتر های a و b به تابع ارسال می کنیم.
طبیعتا هم از قبل اندازه c را آنقدر بزرگ تعریف می کنیم که hi + a + b در آن جا بشود :
کد:
#include <stdio.h>
#include <string.h>

void F(char a[], char b[], char c[])
{
    strcpy(c, "hi");
    strcat(c, a);
    strcat(c, b);
}

int main()
{
    char a[100], b[100], c[210];
    scanf("%s", a);
    scanf("%s", b);
    F(a, b , c);
    printf("%s", c);
    return 0;
}

روش دوم - رشته خروجی به عنوان مقدار بازگشتی تابع بازگردانده شود :
در این روش ما رشته c را در داخل تابع تعریف می کنیم، اما بصورت یک رشته عادی ایجادش نمی کنیم،
چون رشته های عادی موقع ورود به تابع بصورت خودکار ایجاد می شوند و موقع خروج از تابع بصورت خودکار
نابود می شوند. اما رشته هایی که بصورت پویا ایجاد می شوند باید با کد نویسی ایجاد و نابود شوند،
یعنی اگر ما کدی برای این دو عمل ننویسیم، بصورت خودکار نه ایجاد می شوند و نه نابود.

ما کد ایجاد شدن رشته c را در داخل تابع می نویسیم ولی کد نابود شدنش را در تابع قرار نمی دهیم.
کامپایلر برای نابود شدنش کدی را بصورت خودکار اضافه نمی کند و اگر خودمان برای نابود شدن در هنگام
خروج از تابع کدی ننویسیم نابود نمی شود و در بیرون از تابع قابل استفاده است.

البته ما در انتهای تابع main کد نابود شدن c را اضافه می کنیم که قبل از پایان برنامه حافظه تخصیص داده شده
آزاد شود.

کد:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* F(char a[], char b[])
{
    char* c = malloc(210 * sizeof(char));
    strcpy(c, "hi");
    strcat(c, a);
    strcat(c, b);
    return c;
}

int main()
{
    char a[100], b[100];
    char *c;
    scanf("%s", a);
    scanf("%s", b);
    c = F(a, b);
    printf("%s", c);
    free(c);
    return 0;
}

نکته :
موقع استفاده کردن از توابع ()malloc و ()free فراموش نکنید که ابتدا stdlib.h را include کنید.
ضروری نیست، اما اکیدا توصیه می شود که هر چیزی که بصورت پویا حافظه تخصیص داده اید،
پیش از خروج از برنامه حافظه اش را آزاد کنید.
 

one hacker alon

New Member
دوست عزیز ممنون از جواب اما
من میخوام طول رشته ها که 100و100و10 هست رو مشخص نکنم چون امکان داره کاربر در رشته ای با طول 100 کاراکتر 5 کاراکتر وارد کنه یا بیشتر وارد کنه من میخوام طول رشته رو بعد از اینکه کاربر رشته رو وارد کرد تعیین کنم نه اینکه اول برنامه بنویسم char a[100] اصلا همچین چیزی عملی هست؟
یعنی طول رشته برابر طول رشته ای هست که کاربر وارد کرده نه چیزی که خودم در ابتدا وارد کردم
 

the_king

مدیرکل انجمن
دوست عزیز ممنون از جواب اما
من میخوام طول رشته ها که 100و100و10 هست رو مشخص نکنم چون امکان داره کاربر در رشته ای با طول 100 کاراکتر 5 کاراکتر وارد کنه یا بیشتر وارد کنه من میخوام طول رشته رو بعد از اینکه کاربر رشته رو وارد کرد تعیین کنم نه اینکه اول برنامه بنویسم char a[100] اصلا همچین چیزی عملی هست؟
یعنی طول رشته برابر طول رشته ای هست که کاربر وارد کرده نه چیزی که خودم در ابتدا وارد کردم

موقعی که کاربر رشته رو تایپ می کنه که نه، شما باید از قبل پیش بینی کنید که حداکثر چه طولی خواهد داشت،
وگرنه نمی توانید با scanf رشته رو دریافت کنید. زمانی که scanf رو فراخوانی می کنید، scanf فرض رو بر این
قرار داده که شما از قبل حافظه به اندازه کافی تخصیص داده اید، وگرنه بخشی از حافظه تخریب می شود.

اما داخل تابع بله، اگه از روش دوم استفاده کنید می توانید بجای اینکه طول آرایه رو 210 در نظر بگیرید،
طول رشته a و b و "hi" و عدد 1 رو با هم جمع کنید (یک کاراکتر اضافه هم برای null انتهای رشته در نظر بگیرید) و
رشته رو با این طول محاسبه شده ایجاد کنید. چون رشته "hi" دو کاراکتر طول داشت، مقدار 2 را در محاسبه
وارد می کنیم، آن 1 هم که برای جای کاراکتر null انتهای رشته لازم است :
کد:
char* F(char a[], char b[])
{
    int n = strlen(a) + strlen(b) + 2 + 1;
    char* c = malloc(n * sizeof(char));
    strcpy(c, "hi");
    strcat(c, a);
    strcat(c, b);
    return c;
}
 

جدیدترین ارسال ها

بالا