PDA

View Full Version : مشکل در برنامه ای که بدون خطا کامپایل می شود



one hacker alone
شنبه 30 دی 1391, 13:31 عصر
با یاد خدا
با سلام
این برنامه ساده یک فایل رو با نام های مختلف کپی میکنه که بدون خطا هم کامپایل میشه ولی در وقت اجرا خطا خود ویژوال خطا میده
این کد

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string.h>
int main(int argc, _TCHAR* argv[])
{
char a;
for(a='A';a<='Z';a++)
CopyFileA("E:\\1.swf",strcat(strcat("E:\\",(const char*)a),".swf"),1);
return 0;
}


اینم خطا
http://uploadtak.com/images/v334_BUG.jpg

one hacker alone
یک شنبه 01 بهمن 1391, 23:23 عصر
دوستان کسی نیست بگه منطق این برنامه کجاش مشکل داره؟

omidshaman
دوشنبه 02 بهمن 1391, 10:30 صبح
به خاطر اینه که char رو نمیشه همین جوری به پوینتر تبدیل کرد!!
به جای سر و کله زن با strcat و این چیزا از string استفاده کن

#include <iostream>
using namespace std;
int main()
{
string s="E:\\";
int Size=s.size();
s.resize(Size+1);
for(char a='a';a<='z';a++)
{

s[Size]=a;
s.append(".swf");
cout<<s<<"\n";
//karayee ke mikhayo anj bede
s.resize(Size+1);
}
return 0;
}

one hacker alone
دوشنبه 02 بهمن 1391, 18:58 عصر
ممنون اما الان خطای زیر رو میگیره وقتی میخوام s رو بعنوان پارامتر دوم به تابع api پاس بدم

: error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or
there is no acceptable conversion)
error C2664: 'CopyFileA' : cannot convert parameter 2 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'const char *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

shahmohammadi
سه شنبه 03 بهمن 1391, 11:43 صبح
سلام.
ببینید این برنامه درست کار می‌کنه:؟


#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string.h>
int main(int argc, _TCHAR* argv[])
{
char a;
char b[10]="E:\\a.swf";
for(a='A';a<='Z';a++)
{
b[3]=a;
CopyFileA("E:\\1.swf",b,1);
}
return 0;
}




مشکل اول به خاطر این بود که استثنا به وجود می اومد. و مدیریت استثنای سیستم دیباگر پیشفرض سیستمتون رو که همون ویزوال سی بود فراخوانی می کرد.

خطای برنامه ی دوم به خاطر فرق string با LPCSTR هست ولی اگه اجرا شه به نظرم باید دوباره استثنا رخ بده. چون قبل از اینکه s تخصیص حافظه‌ی دوباره شه، چهار کاراکتر بهش اضافه می‌شه.

one hacker alone
چهارشنبه 04 بهمن 1391, 21:37 عصر
ممنون از راهنمایی
کارتون خوب بود یه جورایی یکم خلاقیت می خواست
اما یه چیزی که برام جالبه اینه که چرا b[3] تغییر میکنه در حالی که ادرس این خانه میشه کاراکتر \ و باید ادرس خانه 4 رو میدادیم که اسم فایل بود (البته در خروجی فقط یک بک اسلش ظاهر میشه)
نکته دیگه اینکه کد کار میکنه اما نمیشه گفت کامل هست چون این کد فقط فایلهایی رو تولید میکنه که طول اسم اونها یک کاراکتر هست و اگه ما میخواستیم تعداد فایل ها زیاد باشه مثلا 200 تا اونوقت باید کد تغییر کنه یعنی با کمترین تغییری که بخوایم کد رو راه بندازیم اسم فایل اینجوری میشه aaswf یعنی "." پاک میشه

omidshaman
پنج شنبه 05 بهمن 1391, 08:25 صبح
چون قبل از اینکه s تخصیص حافظه‌ی دوباره شه، چهار کاراکتر بهش اضافه می‌شه.
منظورتون این که
string s="E:\\"; غلطه؟!! البته اینم ۵ کاراکتر اضافه میشه نه ۴ کاراکتر (کاراکتر نول )‌!


s.c_str() به جای s داخل کبی بزار ببین درست میشه

shahmohammadi
جمعه 06 بهمن 1391, 14:27 عصر
اما یه چیزی که برام جالبه اینه که چرا b[3] تغییر میکنه در حالی که ادرس این خانه میشه کاراکتر \ و باید ادرس خانه 4 رو میدادیم که اسم فایل بود (البته در خروجی فقط یک بک اسلش ظاهر میشه)

دوتا / یک کاراکتر محسوب می شند. همونطور که مثلا کارکتر \t یا \0 یا \" یک کاراکتر محسوب می‌شند.



منظورتون این که
string s="E:\\";
غلطه؟!! البته اینم ۵ کاراکتر اضافه میشه نه ۴ کاراکتر (کاراکتر نول
)‌!

نه اینجا رو گفتم که فکر کنم غلطه:

s.append(".swf");

چون به انتهای s چهار کاراکتر اضافه کردید در حالی که s حافظه‌ی اضافی قبلش نگرفته.

omidshaman
جمعه 06 بهمن 1391, 15:24 عصر
چون به انتهای s چهار کاراکتر اضافه کردید در حالی که s حافظه‌ی اضافی قبلش نگرفته.
append کردن نیازی به گرفتن حافظه از قبل نداره.

shahmohammadi
جمعه 06 بهمن 1391, 15:29 عصر
اگه ما میخواستیم تعداد فایل ها زیاد باشه مثلا 200 تا اونوقت باید کد تغییر کنه یعنی با کمترین تغییری که بخوایم کد رو راه بندازیم اسم فایل اینجوری میشه aaswf یعنی "." پاک میشه

#include <conio.h>
#include <stdio.h>
#include <string.h>
int main()
{
char b[20], //string
a
;
int n, //number of copies.
dig=3,//used to create file name
;
strcpy(b,"E:\\");
printf("Enter # of copies you want to create: ");
scanf("%d",&n);
printf("%s",b);
//Create file name
while(n>0)
{
for(a='A'; (a<='Z'); a++,n--)
{
if(n<1)break;
b[dig]=a;
b[dig+1]='\0';
strcat(b,".swf");
printf("\n%s",b);
}//for
if(b[dig]=='Z')
{
b[dig]='A';
dig++;
}
else b[dig]++;
}//while
getch();
return 0;
}
البته چون خواستم نحوه‌ی خلاص شدن از اون استثنا رو بگم، به نحوه‌ی تولید اسم زیاد توجه نکردم. از A تا AZ رو درست می شماره. نیاز به تغییر داره.
برای حل اون استثنا که در نتیجه‌ی بیشتر شدن کاراکتر های الجاقی به رشته از تعداد بایت های اختصاص داده شده بود تعداد کاراکتر ها رو 20 تا در نظر گرفتم که زیاد باشه و این اتفاق نیفته.
برای اشکال مربوط به نام ها هم باید از کدی شبیه به تبدیل مبنا استفاده کنید.

shahmohammadi
جمعه 06 بهمن 1391, 15:55 عصر
append کردن نیازی به گرفتن حافظه از قبل نداره.
درسته برنامه زیر رو امتحان کردم. استثنا نداشت. فکر کنم داخل تابع خودش اول حافظه می‌ده بعد اضافه می کنه.

#include <conio.h>
#include <stdio.h>
#include <string.h>
int main()
{
char b[4] //string
;
strcpy(b,"E:\\");
printf("Enter # of copies you want to create: ");
printf("%s",b);
strcat(b,"13464444444444444444444444444444444444447777777777 77777777777777777777777777777774444444444444444444 44444444444444444444444444444444444444444444444444 444444444478945678");
printf("\n%s",b);
getch();
return 0;
}

omidshaman
جمعه 06 بهمن 1391, 21:16 عصر
البته اینی که شما تست کردی ارایه ای از کاراکتر هاست ربطی به string (توی c++) نداره.
append خودش یک فانکشنه که قبل از اضافه کردن سایز رو افزایش میده.