كيفية الإعلان عن مجموعة من السلاسل في C++؟

StackOverflow https://stackoverflow.com/questions/34987

  •  09-06-2019
  •  | 
  •  

سؤال

أحاول التكرار على جميع عناصر مجموعة ثابتة من السلاسل بأفضل طريقة ممكنة.أريد أن أكون قادرًا على الإعلان عنه في سطر واحد وإضافة/إزالة العناصر منه بسهولة دون الحاجة إلى تتبع الرقم.يبدو الأمر بسيطًا حقًا، أليس كذلك؟

الحلول غير المحتملة:

vector<string> v;
v.push_back("abc");
b.push_back("xyz");

for(int i = 0; i < v.size(); i++)
    cout << v[i] << endl;

المشاكل - لا توجد طريقة لإنشاء المتجه على سطر واحد مع قائمة السلاسل

احتمال غير الحل 2:

string list[] = {"abc", "xyz"};

المشاكل - لا توجد طريقة للحصول على عدد السلاسل تلقائيًا (التي أعرفها).

يجب أن تكون هناك طريقة سهلة للقيام بذلك.

هل كانت مفيدة؟

المحلول

ال تعزيز مكتبة التعيين يبدو أن هذا هو بالضبط ما تبحث عنه.فهو يجعل تعيين الثوابت للحاويات أسهل من أي وقت مضى.

نصائح أخرى

أضاف C++ 11 قوائم التهيئة للسماح بالصيغة التالية:

std::vector<std::string> v = {"Hello", "World"};

تمت إضافة دعم لميزة C++ 11 هذه على الأقل دول مجلس التعاون الخليجي 4.4 وفقط في فيجوال ستوديو 2013.

يمكنك تهيئة a vector<string> من خلق ثابت char* مجموعة مصفوفة:

char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);

بالمناسبة، يؤدي هذا إلى نسخ كافة السلاسل، بحيث تستخدم ضعف الذاكرة.يمكنك استخدام اقتراح Will Dean لاستبدال الرقم السحري 3 هنا بـ arraysize(str_array) - على الرغم من أنني أتذكر وجود بعض الحالات الخاصة التي قد يؤدي فيها هذا الإصدار المعين من arraysize إلى حدوث شيء سيئ (آسف لا أستطيع تذكر التفاصيل على الفور) .لكنها في كثير من الأحيان تعمل بشكل صحيح.

أيضًا، إذا كنت مهتمًا حقًا بالسطر الواحد، فيمكنك تحديد ماكرو متغير بحيث يكون سطر واحد مثل DEFINE_STR_VEC(strvector, "hi", "there", "everyone"); يعمل.

المشاكل - لا توجد طريقة للحصول على عدد السلاسل تلقائيًا (التي أعرفها).

هناك طريقة قياسية للقيام بذلك، والتي يعرفها الكثير من الأشخاص (بما في ذلك مرض التصلب العصبي المتعدد) مثل وحدات الماكرو arraysize ل:

#define arraysize(ar)  (sizeof(ar) / sizeof(ar[0]))

قم بتعريف مجموعة من السلاسل في C++ مثل هذا: char array_of_strings[][]

على سبيل المثال : char array_of_strings[200][8192];

سيحتوي على 200 سلسلة، كل سلسلة بحجم 8 كيلو بايت أو 8192 بايت.

يستخدم strcpy(line[i],tempBuffer); لوضع البيانات في مجموعة من السلاسل.

أحد الاحتمالات هو استخدام مؤشر NULL كقيمة علامة:

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}

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

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));

يمكنك استخدام اقتراح ويل دين [#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))] لاستبدال الرقم السحري 3 هنا بـ arraysize(str_array) - على الرغم من أنني أتذكر وجود بعض الحالات الخاصة التي قد يؤدي فيها هذا الإصدار المعين من arraysize إلى حدوث شيء سيئ (آسف لا أستطيع تذكر التفاصيل على الفور).لكنها في كثير من الأحيان تعمل بشكل صحيح.

الحالة التي لا تعمل فيها هي عندما يكون "المصفوفة" مجرد مؤشر، وليس مصفوفة فعلية.أيضًا، نظرًا للطريقة التي يتم بها تمرير المصفوفات إلى الوظائف (يتم تحويلها إلى مؤشر إلى العنصر الأول)، فإنها لا تعمل عبر استدعاءات الوظائف حتى لو كان التوقيع يبدو كمصفوفة — some_function(string parameter[]) هو حقا some_function(string *parameter).

حاولت التصويت لصالح إجابة Craig H التي يجب عليك استخدامها Boost::sign، لكن ليس لدي مندوب :(

لقد واجهت أسلوبًا مشابهًا في المقالة الأولى التي قرأتها لأندريه ألكسندريسكو مجلة مستخدمي C/C++, ، المجلد 16، العدد 9، سبتمبر 1998، ص.73-74 (احصل على الاقتباس الكامل لأنه موجود في التعليقات الخاصة بتطبيقي للكود الخاص به الذي أستخدمه منذ ذلك الحين).

القوالب هي صديقك.

هنا مثال:

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main() {
    const char* const list[] = {"zip", "zam", "bam"};
    const size_t len = sizeof(list) / sizeof(list[0]);

    for (size_t i = 0; i < len; ++i)
        std::cout << list[i] << "\n";

    const std::vector<string> v(list, list + len);
    std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}

بدلاً من هذا الماكرو، هل يمكنني أن أقترح هذا:

template<typename T, int N>
inline size_t array_size(T(&)[N])
{
    return N;
}

#define ARRAY_SIZE(X)   (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)

1) نريد استخدام الماكرو لجعله ثابتًا في وقت الترجمة؛نتيجة استدعاء الدالة ليست ثابتة في وقت الترجمة.

2) ومع ذلك، لا نريد استخدام ماكرو لأنه قد يتم استخدام الماكرو عن طريق الخطأ على المؤشر.لا يمكن استخدام الدالة إلا على صفائف وقت الترجمة.

لذلك، نستخدم تعريف الوظيفة لجعل الماكرو "آمنًا"؛إذا كانت الوظيفة موجودة (أيحجمه غير صفري) ثم نستخدم الماكرو كما هو مذكور أعلاه.إذا كانت الدالة غير موجودة فإننا نعيد قيمة سيئة.

#include <boost/foreach.hpp>

const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
    cout << str << endl;
}
#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>

int main()
{
    const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
    std::copy(
        v.begin(),
        v.end(),
        std::ostream_iterator< std::string >( std::cout, "\n" ) );
}
#include <iostream.h>
#include <iomanip.h>

int main()
{
int n;
cout<<"enter the maximum number\n";
cin>>n;
cout<<"enter the first number\n";
for(int i=0;i<n;i++)
{

for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
}
cout<<"enter the second number\n";
for(int i=0;i<n;i++)
{
for(int k=0;k<n;k++)
{
cin>>b[i][k];
}
}
cout<<"the product will be\n";
for(int i=0;i<n;i++)
{
for(int g=0;g<n;g++)
{
c[i][g]=c[i][c]*c[i][j];
cout<<setw(5)<<c[i][g];
}
cout<<endl;
}
return 0;
}

يمكنك الإعلان مباشرة عن مجموعة من السلاسل مثل string s[100];.ثم إذا كنت ترغب في الوصول إلى عناصر محددة، يمكنك الحصول عليها مباشرة s[2][90].لأغراض التكرار، خذ حجم السلسلة باستخدامs[i].size() وظيفة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top