اذهب إلى المحتوى

السؤال

نشر

لدي نص بسيط كالتالي ويتحتوي على العديد من المسافات في بدايته وفي نهايته أيضًا:
 

std::string s =   "  Hello world   ";

في لغات أخرى مثل JavaScript يمكنني أقوم بإستخدام التابع trim للقيام بهذه المهمة، ولكن كيف بعمل دالة تؤدي نفس المهمة في ++C؟

Recommended Posts

  • 1
نشر

يمكنك أن تقوم بعمل دالة left-trim ، كالتالي:

const char* wihte_spaces = " \t\n\r\f\v";

// إزالة المسافات الزائدة من بداية النص
std::string& ltrim(std::string& str, const char* ws = wihte_spaces)
{
    str.erase(0, str.find_first_not_of(ws));
    return str;
}

تقوم الدالة السابقة بإستقبال النص كمدخل لها وتعيد نفس النص بعد إزالة المسافات الزائدة من بدايته، لاحظ كيف تم إستخدام الثابت wihte_spaces والذي يحتوي على كل أشكال المسافات، وفي الدالة نفسها نقوم بحذف كل هذه المسافات من البداية (index 0)

ويمكن إستخدام نفس الطريقة لعمل دالة rtrim:

std::string& rtrim(std::string& str, const char* ws = wihte_spaces)
{
    str.erase(str.find_last_not_of(ws) + 1);
    return str;
}

تقوم هذه الدالة بحذف المسافات من نهاية النص، لاحظ كيفية إستخدام التابع find_last_not_of وإضافة 1 إلى القيمة المرجعة.

الآن يمكنك أن تقوم ببساطة عمل دالة تسمى trim تقوم بتنفيذ الدالتين السابقتين، على النحو التالي:
 

// ستقوم هذه الدالة بحذف المسافات من بداية ونهاية النص المدخل إليها
std::string& trim(std::string& str, const char* ws = wihte_spaces)
{
    return ltrim(rtrim(str, ws), ws);
}

ستقوم هذه الدالة بإستدعاء كلٍ من ltrim و rtrim ثم إرجاع النص بعد إزالة المسافات من بدايته ونهايته.

الآن يمكنك إستخدام الدالة الأخيرة كالتالي:
 

std::string s =   "  Hello world   ";
std::cout << trim(s);	// Output: "Hello world"
  • 0
نشر

إليك الكود التالي الذي يقوم بحذف كل المسافات الزائدة في أي مكان من الجملة، على سبيل المثال:

Input: 
	"   Remove extra spaces     from a string   , c++  .   "
Output: 
	"Remove extra spaces from a string, c++."

الحل هو بالاحتفاظ بمؤشرين كلاهما يشير إلى بداية المصفوفة، بحيث يتتبع المؤشر الأول الموضع التالي ليتم ملؤه في سلسلة الخرج. أما الثاني لقراءة جميع أحرف السلسلة واحداً تلو الآخر. الآن عند إيجاد أي محرف بدون مسافة، يتم نسخ المحرف إلى موقع المؤشر الأول ثم يتم تقديم كل من المؤشرين الأول والثاني، وإذا كان المحرف الذي لا يحتوي على مسافة عبارة عن نقطة أو فاصلة أو علامة استفهام، فإننا نزيل أي مسافة سابقة قبله.
أيضاً عند إيجاد مسافات متتالية، يتم نسخ مسافة واحدة فقط إلى موقع المؤشر الأول ويتم تجاهل الباقي. يتم التعامل مع المسافات البادئة والزائدة بشكل منفصل في الحل.

#include <iostream>
using namespace std;
void removEextraSpace(string &myStr)
{
	int firstPtr = 0; // تعريف المؤشر الأول
	int secondPtr= -1; // تعريف المؤشر الثاني
	// إشارة للتحقق فبما إذا كنا قد وجدنا مسافة أم لا
	bool space = false;
	// لمعالجة المسافات في البداية
	while (++secondPtr < myStr.length() && myStr[secondPtr] == ' ');
	// قراءة كل المحارف من السلسلة
	while (secondPtr < myStr.length())
	{
		// إذا لم يكن المحرف الحالي مسافة
		if (myStr[secondPtr] != ' ')
		{
			// حذف المسافات التي تسبق النقطة واشاؤة الاستفهام 
			if ((myStr[secondPtr] == '.' || myStr[secondPtr] == ',' ||
				myStr[secondPtr] == '?') && firstPtr - 1 >= 0 &&
				myStr[firstPtr - 1] == ' ')
				myStr[firstPtr - 1] = myStr[secondPtr++];

			else
				//  ال المحرف الحالي عند الفهرس المحدد بالمؤشر الأول، 
				myStr[firstPtr++] = myStr[secondPtr++];  // تقديمهم خطوة
            // وضع الإشارة على خاطئ في حالة عدم مصادفة مسافة
			space = false;
		}
		// حلة المحرف الحالي هو مسافة
		else if (myStr[secondPtr++] == ' ')
		{
            // إذا تمت مصادفة مسافة لأول مرة بعد الكلمة ، فضع مسافة واحدة في الإخراج واضبط  الإشارة على صحيح
			if (!space)
			{
				myStr[firstPtr++] = ' ';
				space = true;
			}
		}
	}

	// إزالة المسافات الزائدة 
	if (firstPtr <= 1)
		myStr.erase(myStr.begin() + firstPtr, myStr.end());
	else
		myStr.erase(myStr.begin() + firstPtr - 1, myStr.end());
}
// الاختبار
int main()
{
	string str = "   Remove extra spaces     from a string   , c++  .   ";
	removEextraSpace(str);
	cout << str;
	return 0;
}
/*
String after removing extra spaces:
Remove extra spaces from a string, c++.
*/

 

  • 0
نشر

يمكنك إستخدام الدالة erase بالإضافة مع الدالة remove_if حيث تقوم بإعطاء الدالة remove_if مؤشر لبداية النص ونهايته والحرف الذي تريد إزالته , وتقوم بتمرير الدالة كمعامل اول للدالة erase ومن ثم تقوم بإعطاء مؤشر لنهاية النص كمعامل ثاني

كما بالشكل التالي 

input.erase(remove_if(input.begin(), input.end(), isspace),input.end());

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

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

×   جرى استعادة المحتوى السابق..   امسح المحرر

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

  • إعلانات

  • تابعنا على



×
×
  • أضف...