SCANF لا يتجاوز تجاوز المخزن المؤقت
سؤال
لدي مخزن مؤقت ولا أريد إدخال المستخدمين إدخال المزيد من الأحرف غير المخزن المؤقت يمكن أن يحمل (لتجنب تجاوز المخزن المؤقت).
انا استخدم scanf
وقد فعلت مثل هذا:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
ومع ذلك، أعلم أنني محمي إذا كان المستخدم يدخل أكثر من 30. ومع ذلك، إذا كان المستخدم يدخل أكثر من 30، فسيتم إنهاء المخزن المؤقت NULL؟
المحلول
scanf()
باستخدام جهاز تحويل "٪ S" يضيف حرفا فارغا إلى المخزن المؤقت.
ولكن, ، أنت تسأل عن 30 حرفا، والتي تعني حقا 31 ولا تملك فقط مساحة 30. يجب عليك استخدام عرض حقل أقصى من 29.
char buffer[30] = {'\0'};
scanf("%29s", buffer);
لاحظ أيضا أن محدد التحويل "%c"
يعمل كثيرا مثل "%s"
, ولكن لا يضيف "إنهاء حرف Null" ولا يتجاهل المساحة من المدخلات. اعتمادا على ما تتوقعه، قد يكون أفضل من استخدام "٪ S".
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
نصائح أخرى
من scanf
كتيب:
س يطابق سلسلة من الأحرف غير البيضاء؛ يجب أن يكون المؤشر التالي مؤشرا للسحر، ويجب أن يكون الصفيف كبيرا بما يكفي لقبول كل التسلسل وحرف NUL المنتهي. تتوقف سلسلة الإدخال على مساحة بيضاء أو في الحد الأقصى لعرض الحقل، أيهما يحدث أولا.
أنت تستدع UB. يحاول:
#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30
char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);
لتجاهل أي شيء وراء BUFSIZE
الأحرف قمع المهمة:
scanf("%" xstr(BUFSIZE) "s%*", buf);
يجب عليك أيضا التحقق مما إذا كان المستخدم قد دخل العودة / Newline وإنهاء scanf
إذا كان لديه:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
ومن الممارسات الجيدة التحقق من قيم العودة، لذلك:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
وأخيرا، تحقق مما إذا كان هناك أي شيء يترك (مثل Newline، واستهلكه):
if (!feof(stdin))
getchar();
سيكون لديك تجاوز مخزن مؤقت لأنك لم يسمح لك بإنهاء حرف NUL. أعلن المخزن المؤقت الخاص بك مثل هذا:
char buffer[31];
وسوف تكون على ما يرام.