كيفية تحويل سلسلة بشكل محمول إلى نوع عدد صحيح غير شائع؟

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

سؤال

بعض الخلفية:إذا أردت استخدام، على سبيل المثال، scanf() لتحويل سلسلة إلى نوع عدد صحيح قياسي، مثل uint16_t, ، سأستخدمه SCNu16 من <inttypes.h>, ، مثله:

#include <stdio.h>
#include <inttypes.h>
uint16_t x;
char *xs = "17";
sscanf(xs, "%" SCNu16, &x);

ولكن هناك نوع صحيح غير شائع مثل pid_t ليس لديه أي شيء من هذا القبيل.يتم دعم أنواع الأعداد الصحيحة العادية فقط <inttypes.h>.للتحويل بالطريقة الأخرى إلى المحمولة printf() أ pid_t, ، أستطيع أن ألقي عليه intmax_t والاستخدام PRIdMAX, ، مثله:

#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
pid_t x = 17;
printf("%" PRIdMAX, (intmax_t)x);

ومع ذلك، لا يبدو أن هناك طريقة للنقل scanf() الى pid_t.لذلك هذا هو سؤالي:كيفية القيام بذلك محمولا؟

#include <stdio.h>
#include <sys/types.h>
pid_t x;
char *xs = 17;
sscanf(xs, "%u", &x);  /* Not portable! pid_t might not be int! /*

فكرت في scanf()جي إلى intmax_t ومن ثم التحقق من أن القيمة داخل pid_tحدود قبل الإرسال إلى pid_t, ، ولكن لا يبدو أن هناك طريقة للحصول على الحد الأقصى أو الحد الأدنى للقيم pid_t.

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

المحلول

هناك حل واحد قوي ومحمول، وهو الاستخدام strtoimax() والتحقق من الفائض.

وهذا هو، أنا تحليل intmax_t, ، تحقق من وجود خطأ من strtoimax(), ، ثم تحقق أيضًا مما إذا كان "مناسبًا" لـ a pid_t من خلال صبها ومقارنتها بالأصل intmax_t قيمة.

#include <inttypes.h>
#include <stdio.h>
#include <iso646.h>
#include <sys/types.h>
char *xs = "17";            /* The string to convert */
intmax_t xmax;
char *tmp;
pid_t x;                    /* Target variable */

errno = 0;
xmax = strtoimax(xs, &tmp, 10);
if(errno != 0 or tmp == xs or *tmp != '\0'
   or xmax != (pid_t)xmax){
  fprintf(stderr, "Bad PID!\n");
} else {
  x = (pid_t)xmax;
  ...
}

ليس من الممكن استخدامها scanf(), لأنه (كما قلت في تعليق) scanf() لن تكتشف الفيضانات.ولكنني كنت مخطئا في القول بأن أيا من strtoll()الوظائف ذات الصلة تأخذ intmax_t; strtoimax() يفعل!

كما أنه لن يجدي استخدام أي شيء آخر غير strtoimax() إلا إذا كنت تعرف حجم نوع العدد الصحيح الخاص بك (pid_t, ، في هذه الحالة).

نصائح أخرى

وهذا يعتمد على بالضبط كيف المحمولة كنت تريد أن تكون. يقول POSIX التي pid_t هو نوع عدد صحيح وقعت تستخدم لمعرفات عملية تخزين ومعرفات مجموعة العملية. في الواقع، يمكن أن نفترض مع السلامة التي long هي كبيرة بما يكفي. إذا تعذر ذلك، يجب أن يكون لديك intmax_t كبيرة بما يكفي (حتى انها لن تقبل أي pid_t سارية المفعول). والمشكلة هي، هذا النوع يمكن أن يقبل القيم التي ليست مشروعة في pid_t. كنت عالقا بين المطرقة والسندان.

وأود أن استخدام long ولا تقلق كثيرا حول هذا الموضوع باستثناء تعليق غامضة في مكان ما أن عالم الآثار البرمجيات من 100 سنة وبالتالي سوف تجد ومراقبة يعطي السبب في وحدة المعالجة المركزية 256 بت يئن تحت وطأتها إلى توقف عندما سلمت 512 قيمة بت باعتباره pid_t.

POSIX 1٬003،1-2008 أصبحت الآن متاحة على شبكة الإنترنت (جميع 3872 صفحات منه، في PDF و HTML). لديك لتسجيل (مجاني). حصلت عليه من المجموعة المفتوحة مكتبة .

وكل ما أرى هناك هو أنه يجب أن يكون هناك نوع عدد صحيح وقعت. ومن الواضح أن كل قيم الأعداد الصحيحة وقعت صحيحة تنسجم مع intmax_t. لا أستطيع أن أجد أي معلومات في <inttypes.h> أو <unistd.h> يشير PID_T_MAX أو PID_T_MIN أو غير ذلك من القيم (ولكن أنا عندي فقط فقط هذا المساء الوصول إليها، لذلك يمكن أن تكون مخفية حيث أنا لم ينظر لذلك). OTOH، والوقوف إلى جانب تعليقي الأصلي - وأعتقد أن القيم 32-بت كافية عمليا، وأود أن استخدام long على أي حال، والتي ستكون 64 بت على أجهزة 8 بت. أفترض أن ما يقرب من أسوأ شيء يمكن أن يحدث هو أن عملية "مميزة بشكل مناسب" قراءة قيمة التي كانت كبيرة جدا، وأرسلت إشارة إلى عملية خاطئة بسبب عدم تطابق أنواع. أنا غير مقتنع سأكون قلقا بشأن ذلك.

... أووه! ... P400 تحت <sys/types.h>

<اقتباس فقرة>   

ويجب تنفيذ دعم واحد أو أكثر من البرامج البيئات التي الاعراض   من blksize_t، pid_t، size_t، ssize_t، وsuseconds_t توجد أكبر من عرض من نوع طويلة.

إذا كنت قلقا حقا يمكنك _assert(sizeof(pid_t) <= long) أو أيا كان نوع اخترت لما تبذلونه من الاشياء '٪'.

وكما هو موضح في هذه الإجابة ، والمواصفات وتقول signed int. إذا كانت التغييرات "كثافة"، الخاص بك '٪ ش' بالتغيرات تعريف معها.

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