الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]مشكلة ادخال الاحرف

بدأه faisal_alsubaie في 15 سبتمبر 2012 · 14 رد · 935 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة لله وبركانة

انا حبيت اكتب برنامج يقوم المستخدم بادخال الاحرف ومن ثم تظره لة ولكن هناك مشكلة وهي تكرار الحرف الاول

وهذا هو الكود المستخدم

#include <stdio.h>

int main()
{
	char ch1,ch2;
	printf("Enter  farst char neme ");
	scanf("%c\n",&ch1);
	printf("enter your secand  char name");
	scanf("%c\n",&ch2);
	printf ("your first cahr is %c and your secand char is %c \n",ch1,ch1);
	return 0;
}
#2

السلام عليكم

أخى الكريم واضح من الكود أن كودك صحيح ولكن أنت تقوم بطباعة المتغير ch1 مرتين وبالتالى سيتم طباعة قيمة المتغير الأول مرتين .

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

لا إله إلا أنت سبحانك إني كنت من الظالمين

#3

صحيح شكرا لك

#4

السلام عليكم

المفروض أن الإسم يكون سلسلة حروف و ليس حرف واحد فقط :)

أيضا, خطأك كان يكمن في استخدام الرمز \n في scanf.

التصحيح :

#include <stdio.h>

int main()
{
		  char ch1[50],ch2[50];
		  printf("Enter first name : ");
		  scanf("%s",ch1);
		  printf("Enter your second name : ");
		  scanf("%s",ch2);
		  printf ("your first name is %s and your second name is %s \n",ch1,ch2);
		  return 0;
}

المُخرجات :

post-219439-053756900 1347694863_thumb.p

أطيب التحية.

المرفقات
test.png
#5

بس المشكلة طلعت لي هذا

post-249057-040092100 1347694981_thumb.p

أحمد الشنقيطي كتب:

السلام عليكم

المفروض أن الإسم يكون سلسلة حروف و ليس حرف واحد فقط :)

أيضا, خطأك كان يكمن في استخدام الرمز \n في scanf.

التصحيح :

#include <stdio.h>

int main()
{
		  char ch1[50],ch2[50];
		  printf("Enter first name : ");
		  scanf("%s",ch1);
		  printf("Enter your second name : ");
		  scanf("%s",ch2);
		  printf ("your first name is %s and your second name is %s \n",ch1,ch2);
		  return 0;
}

المُخرجات :

post-219439-053756900 1347694863_thumb.p

أطيب التحية.

اشكرك على المجهود لكن انا ابي مثل الطريقة ولكن انا ادخل حرفي الاول والحرف الثاني و ليس الاسم كامل ولك جزيل الشكر

المرفقات
Screenshot from 2012-09-15 10:41:58.png
#6

إذا, استخدم الدالة getche الموجودة في conio.h على أنظمة الويندوز أو stdio.h على أنظمة لينكس :

#include <stdio.h>
#include <conio.h>

int main() {
    char ch1, ch2;
    printf("Enter first char name : ");
    ch1 = getche();
    printf("\nEnter your second char name : ");
    ch2 = getche();
    printf("\nyour first char is %c and your second char is %c \n", ch1, ch2);
    return 0;
}

المخرجات :

post-219439-042201200 1347696142_thumb.p
المرفقات
test.png
#7

السلام عليكم

لديك خطأ فى دالة scanf أشار لهذا أخى أحمد , فقط أزل علامة \n من دالة scanf .

جميل أنك تستخد نظام لينكس , لماذا لا تستخدم محرر NetBeans ستجده فى مركز التطبيقات الخاص بـ ubuntu فهو محرر رائع ويدعم عده لغات عديدة أخرى , وهناك أيضاً العديد من المحررات الأخرى التى تدعم لغة c/c++ يمكنك تجربتها .

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

لا إله إلا أنت سبحانك إني كنت من الظالمين

#8
اقتباس
هذا مو حق الجافا ؟

الــ Netbeans صُمم أصلا للجافا لكنه أصبح الآن يدعم مُعظم لغات البرمجة (C, C++, J2SE, J2EE, J2ME, FORTRAN, PHP, ...), كما أنه سريع, خفيف, مجاني, و متعدد المنصات.(تماماً مثل QT مع C++)

post-219439-016221500 1347698743_thumb.p
المرفقات
NetBeans.png
#9

وعليكم السلام و رحمة الله

int  scanf ( const char * format, ... );

عندما تقوم بإدخال حرف عبر الدالة scanf فإنك لا تدخل حرفا واحدا وفقط بل حرفين !!!

كيف هذا؟

scanf("%c",&ch1);

لندخل الحرف k كما هو مبين في الصورة

1347703132241.jpg

الدالة scanf لن تتوقف إلا لما تصادف 'n\' أو 't\' أو فراغ (espace)

وبالتالي فأنت مجبر على الضغط على الزر entree مثلا

عندما تقوم بالضغط على entree فأنت بهذه الحالة تدخل حرفين لل buffer stdin

الحرف الأول سيكون الحرف 'k' الذي أدخلته أنت في البداية و الحرف التاني سيكون 'n\'

لحد الآن أدخلنا حرفين هما 'n\' و 'k'

عندما نريد إدخال حرف آخر غير الحرف الأول 'k' الذي أدخلناه عبر scanf

scanf("%s",ch2);

في هذه الحالة ستقوم scanf باسترداد الأحرف المتبقية في ال buffer stdin و ستتجاهل طلبك

الخلاصة

ch1 ستأخد القيمة 'k' و ch2 ستأخد القيمة 'n\'

ch1='k';
ch2='\n';

ولك أن تتأكد بنفسك عبر هذا المثال

 #include <stdio.h>

int main()
{   	char a=0;
    	printf("entrer une charactere:");
    	scanf("%c",&a);
    	printf("entrer une charactere:");
    	scanf("%c",&a);
    	putchar('\n');
    	printf("%d",(int)a); // ==>10 ==> new line(table ascci)(رجوع للسطر) '\n'
    	return 0;
}

للتغلب على هذه المشكلة يلزمك تفريغ buffer stdin

#include <stdio.h>

int main()
{
    	char ch1=0,ch2=0;
    	printf("Enter  farst char neme :\t");
    	ch1=getchar();
    	fgetc(stdin);   //buffer stdin لتفريغ حرف واحد في ال
    	printf("enter your secand  char name:\t");
    	ch2=getchar();
    	printf("your first cahr is %c and your secand char is %c \n",ch1,ch2);
    	return 0;
}

1347703132282.jpg

وهذا الكود صالح في حالة ما أدخلنا حرفا واحد و فقط عبر الدالة scanf

أما إذا أدخل المستخدم عدة أحرف

فاستعن بهذه الدالة مثلا

void viderBuffer()
{
	int c = 0;
	while (c != '\n' && c != EOF)
	{
    	c = getchar();
	}
}

وفقك الله

تم تعديل هذه المشاركة بواسطة مومو (momo) في 15 سبتمبر 2012 في 15:49

2

i love you mama

#10

أحسنت أخي مومو :)

int fflush(FILE *stream);

لإفراغ الــ buffer يمكن أيضا استخدام الدالة fflush هكذا :

fflush(stdin);
1
#11

فى ++std C يمكن استخدام ignore for istream

// istream ignore
#include <iostream>
#include <climits>
using namespace std;

int main () {
  char first, last;

  cout << "Enter your first and last names: ";

  first=cin.get();
  cin.ignore(INT_MAX,'\n');

  last=cin.get();

  cout << "Your initials are " << first << last;

  return 0;
}

http://www.cplusplus.com/reference/iostream/istream/ignore/

flush for ostream

http://www.cplusplus.com/reference/iostream/ostream/flush/

1


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#12

اسمح لي بتعليق بسيط أستاذي محمد :)

بداية .. الدالة cin.ignore تتعامل مع الـ buffer ..! فما هو الـbuffer !؟ و ما هي فائدته !؟

الـ buffer هو جزء من الذاكرة يتم تخزين المعلومات فيه مؤقتاً قبل أن تكمل طريقها للمعالجة, عادة ما يكون مصدر المعلومات هو أحد وحدات الإدخال مثل الكيبورد أو الإخراج مثل الطابعة.

الفائدة منه : كما نعلم فإن الفرق هائل بين الزمن اللازم لإدخال المعلومات والزمن اللازم لمعالجتها, فالأخير أقل بكثير .. ولا يمكن للمعلومات أن تنتقل مباشرة من الكيبورد إلى المعالج, لذلك يتم تخزينها في الـ buffer (عند وقت الإدخال) ثم تنتقل بعد ذلك إلى المعالج, نفس الشيء إذا قمنا باستعمال الطابعة .. حينها سيتم استخدام الـ Buffer (لتخزين البيانات) حيث تتم معالجتها بعد اكتمال وصولها.

كخلاصة : يمكننا أن القول بأن الـ Buffer ما هو إلا حلقة وصل بين وحدات (الإدخال/الإخراج) و المعالج و يتم استخدامه عندما تنتقل البيانات بين طرفين يختلفان في السرعة .. عندها يتم استخدام الـ buffer (كمرحلة مؤقتة) لتخزين البيانات لحين اكتمال وصولها ثم تنتقل بعد ذلك للمعالج لتتم معالجتها.

نأتي الآن لشرح كيفية عمل الدالة cin.ignore :

يمكننا استدعاء الدالة بثلاث طرق :

1. كما هي دون أن تأخذ معاملات (و هي الحالة الإفتراضية) : cin.ignore();, بهذه الطريقة سيتم حذف حرف واحد من الـ buffer.

2. أن تأخذ معاملاً واحداً (عدداً صحيحاً) وهو عدد الحروف التي سيتم حذفها من الـbuffer :

cin.ignore(30);

و في هذه الحال سيتم حذف 30 حرف من الـ buffer.

3. أن تأخذ معاملين هكذا :

cin.ignore(53,'Q');

الوسيط الأول هو عدد الأحرف التي سيتم حذفها من الـ buffer ,و إذا تم العثور على حرف مُساوي للوسيط الثاني, سيتم التوقف عن الحذف .. أي أن عملية حذف الأحرف من الـ buffer تتوقف عند العثور على أول حرف مشابه للوسيط الثاني.

في هذا المثال فإنه قبل نهاية الـ 53 حرف سيتم حذف الأحرف حتى أول ظهور لـ 'Q' (و لن يتم انتزاع 53 حرف).

و إذا لم يظهر الوسيط الثاني في أول 53 حرف فسيتم حذف الـ 53 حرف جميعها من ال buffer.

مثال :

#include <iostream>
using namespace std;

int main() {
    char phrase[30];
    cout << "entrez une phrase:";
    cin.ignore(10, 'm');
    cin.get(phrase, 29);
    cout << phrase << endl;
    return 0;
}

بالإضافة إلى ما ذكره الأخ محمد, توجد طريقة أخرى لإفراغ الــ Buffer في C++ باستخدام التابع cin.sync لنتظيف الـ buffer من المُدخلات الخاطئة (العالقة) بالإضافة إلى التابع cin.clear لإعادة حالة cin.fail إلى الوضع الطبيعي.

توجد أيضا توابع أخرى مهمة في عملية الإدخال مثل التابع cin.putback, الذي يقوم بإرجاع الحرف الملتقط بواسطة الدالة get إلى قناة الإدخال مرة أخرى.

1
#13

جيد اخ احمد

cin.putback جميلة جدا هذه الدالة تستخدم فى عمل parser

انظر هذا المثال من مخترع اللغة

/****************************************HEADERS***************************************************/

#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <cctype>
using namespace std;



/****************************************GLOBAL VARIABLES****************************************/

enum Token_value
{
      NAME,		NUMBER,		END,
      PLUS='+',	MINUS='-',		MUL='*',		DIV='/',
      PRINT=';',	ASSIGN='=',		LP='(',		RP=')',
};

Token_value curr_tok = PRINT;
double number_value;
string string_value;
map<string,double> table;
int no_of_errors;
istream* input;			//pointer to input stream



/****************************************FUNCTIONS CALLS*****************************************/

double expr(bool get);
double term(bool get);
double prim(bool get);
Token_value get_token();
double error(const string& s);



/*****************************************MAIN******************************************************/

int main(int argc, char* argv[])
{
      switch (argc)
      {
	  case 1 :				// read from standard input
	        input = &cin;
	        break;
	  case 2 :
	        input = new istringstream(argv[1]);		// read argument string
	        break;
	  default :
	        error ("Too many arguments");
	        return 1;
      }

      table["pi"] = 3.1415926535897932385;		// insert predefined names
      table["e"] = 2.7182818284590452354;

      while (*input)
      {
	  get_token();
	  if (curr_tok == END) break;
	  if (curr_tok == PRINT) continue;
	  cout<< expr(false) <<endl;
      }

      if (input != &cin) delete input;
      return no_of_errors;
}



/*****************************************OTHER FUNCTIONS*****************************************/

double expr(bool get)				// add and substract
{
      double left = term(get);

      for(;;)
	  switch (curr_tok)
	  {
	        case PLUS :
		    left += term(true);
		    break;
	        case MINUS :
		    left -= term(true);
		    break;
	        default :
		    return left;
	  }
}



double term(bool get)				// multiply and divide
{
      double left = prim(get);

      for (;;)
	  switch (curr_tok)
	  {
	        case MUL :
		    left *= prim(true);
		    break;
	        case DIV :
		    if (double d = prim(true))
		    {
			left /= d;
			break;
		    }
		    return error("Divide by 0");
	        default :
		    return left;
	        }
}



double prim(bool get)				// handle primaries
{
      if (get) get_token();

      switch (curr_tok)
      {
	  case NUMBER :			// floating point constant
	  {
	        double v = number_value;
	        get_token();
	        return v;
	  }
	  case NAME :
	  {
	        double& v = table[string_value];
	        if (get_token() == ASSIGN) v = expr(true);
	        return v;
	  }
	  case MINUS :			// unary minus
	        return -prim(true);
	  case LP :
	  {
	        double e = expr(true);
	        if (curr_tok != RP) return error("')' expected");
	        get_token();			//eat ')'
	        return e;
	  }
	  default :
	        return error("primary expected");
      }
}




Token_value get_token()
{
      char ch = 0;
      do { if(!cin.get(ch)) return curr_tok = END; }		// skip whitespace except '\n'
      while (ch != '\n' && isspace(ch));
      switch (ch)
      {
	  case 0 :
	        return curr_tok=END;
	  case ';' :
	  case '\n' :
	        return curr_tok = PRINT;
	  case '*' :
	  case '/' :
	  case '+' :
	  case '-' :
	  case '(' :
	  case ')' :
	  case '=' :
	        return curr_tok = Token_value(ch);

	  case '0' :	case '1' :	case '2' :	case '3' : 	case '4' :
	  case '5' :	case '6' :	case '7' :	case '8' :	case '9' :
	  case '.' :
	        cin.putback(ch);
	        cin >> number_value;
	        return curr_tok = NUMBER;
	  default:				// NAME, NAME =, or error
	        if (isalpha(ch))
	        {
		    string_value = ch;
		    while (cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
		    cin.putback(ch);
		    return curr_tok = NAME;
	        }
	        error("Bad Token");
	        return curr_tok = PRINT;
      }
}



double error(const string& s)
{
      no_of_errors++;
      cerr << "error : " << s << '\n';
      return 1;
}

تحياتى


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#14
مومو (momo) كتب:

وعليكم السلام و رحمة الله

int  scanf ( const char * format, ... );

عندما تقوم بإدخال حرف عبر الدالة scanf فإنك لا تدخل حرفا واحدا وفقط بل حرفين !!!

كيف هذا؟

scanf("%c",&ch1);

لندخل الحرف k كما هو مبين في الصورة

1347703132241.jpg

الدالة scanf لن تتوقف إلا لما تصادف 'n\' أو 't\' أو فراغ (espace)

وبالتالي فأنت مجبر على الضغط على الزر entree مثلا

عندما تقوم بالضغط على entree فأنت بهذه الحالة تدخل حرفين لل buffer stdin

الحرف الأول سيكون الحرف 'k' الذي أدخلته أنت في البداية و الحرف التاني سيكون 'n\'

لحد الآن أدخلنا حرفين هما 'n\' و 'k'

عندما نريد إدخال حرف آخر غير الحرف الأول 'k' الذي أدخلناه عبر scanf

scanf("%s",ch2);

في هذه الحالة ستقوم scanf باسترداد الأحرف المتبقية في ال buffer stdin و ستتجاهل طلبك

الخلاصة

ch1 ستأخد القيمة 'k' و ch2 ستأخد القيمة 'n\'

ch1='k';
ch2='\n';

ولك أن تتأكد بنفسك عبر هذا المثال

 #include <stdio.h>

int main()
{   	char a=0;
    	printf("entrer une charactere:");
    	scanf("%c",&a);
    	printf("entrer une charactere:");
    	scanf("%c",&a);
    	putchar('\n');
    	printf("%d",(int)a); // ==>10 ==> new line(table ascci)(رجوع للسطر) '\n'
    	return 0;
}

للتغلب على هذه المشكلة يلزمك تفريغ buffer stdin

#include <stdio.h>

int main()
{
    	char ch1=0,ch2=0;
    	printf("Enter  farst char neme :\t");
    	ch1=getchar();
    	fgetc(stdin);   //buffer stdin لتفريغ حرف واحد في ال
    	printf("enter your secand  char name:\t");
    	ch2=getchar();
    	printf("your first cahr is %c and your secand char is %c \n",ch1,ch2);
    	return 0;
}

1347703132282.jpg

وهذا الكود صالح في حالة ما أدخلنا حرفا واحد و فقط عبر الدالة scanf

أما إذا أدخل المستخدم عدة أحرف

فاستعن بهذه الدالة مثلا

void viderBuffer()
{
	int c = 0;
	while (c != '\n' && c != EOF)
	{
    	c = getchar();
	}
}

وفقك الله

كلام جميل و الحمد لله عمل البرنامج على اكمل وجة ولكن هل اختلاف المترجم يؤثر في عمل الاكواد

#15
اقتباس
هل اختلاف المترجم يؤثر في عمل الاكواد

الــ IDE القديمة (مثل Borland C++ 4.5) لا تدعم مساحات الأسماء (Namespaces) في C++ و لا المتغيرات المنطقية (Boolean variables) في C لأنها لم تكن موجودة آنذاك. (المعيار C99 هو الذي أدخل هذه المفاهيم الجديدة و BC45 تم تصميمه سنة 1995).

لكن بشكل عام, أي IDE تم تصميمه بعد سنة 2003 سيكون مناسبا كبداية :)

مواضيع مشابهة