Як апрацоўваць NULL, які ў цяперашні час атрымаў ад асноўнай. C ++

I am new to C++. I have a function called isValid(const char str[]);

int isValid (const char str[])
{
  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
  if (str==NULL)
     return 0;
  if (atol(str)==1234567890)
     return 1;
}

ўзор MAIN:

int main(void)
{
   char test[10];
   cout<<"Testing NULL"<<< isValid(NULL)<<<"Testing isValid"<<"Enter test: ";
   cin>>test;
   cout<<

Я атрымліваю гэта:

<�Р> Тэсціраванне NULL      <�Р> памылка сегментаванне

Як рэалізаваць NULL. Дзякуй!

0
Што б вы хацелі, каб адбылося? Альбо праверыць, калі значэнне, перададзенае ў NULL , і мець справу з ім адпаведным чынам, або хай гэта ўрэзацца ...
дададзена аўтар Mats Petersson, крыніца
Што б вы хацелі, каб адбылося? Альбо праверыць, калі значэнне, перададзенае ў NULL , і мець справу з ім адпаведным чынам, або хай гэта ўрэзацца ...
дададзена аўтар Mats Petersson, крыніца
Дадаць праверку NULL , і прыняць адпаведныя меры.
дададзена аўтар Oliver Charlesworth, крыніца
Дадаць праверку NULL , і прыняць адпаведныя меры.
дададзена аўтар Oliver Charlesworth, крыніца

13 адказы

Парадак выпрабаванняў у IsValid няправільна - вы павінны праверыць NULL першы перад выклікам StrLen або разнаймення вул ,

Акрамя таго, было яшчэ некалькі памылак:

isValid needs to add a return value for the case that none of your if conditions are satisfied. I'd have expected this to generate a warning. If it didn't, compiling with warnings enabled (/W4 for MSVC, -Wall for gcc) would have flagged it.

i isn't defined so isdigit(str[i]) wouldn't compile. My updated code (below) shows how to confirm that each character in str is a digit

int isValid (const char str[])
{
    if (str==NULL)
        return 0;
    size_t len = strlen(str);
    if (len != 10)
        return 0;
    for (size_t i=0; i
3
дададзена
што я у вул [я] ?
дададзена аўтар Pixelchemist, крыніца
Дзякуй, я скапіяваў з гэтага пытання і не заўважыў, што гэта не будзе кампілявацца. Ці будзе абнаўленне/выправіць у секунду
дададзена аўтар simonc, крыніца

Парадак выпрабаванняў у IsValid няправільна - вы павінны праверыць NULL першы перад выклікам StrLen або разнаймення вул ,

Акрамя таго, было яшчэ некалькі памылак:

isValid needs to add a return value for the case that none of your if conditions are satisfied. I'd have expected this to generate a warning. If it didn't, compiling with warnings enabled (/W4 for MSVC, -Wall for gcc) would have flagged it.

i isn't defined so isdigit(str[i]) wouldn't compile. My updated code (below) shows how to confirm that each character in str is a digit

int isValid (const char str[])
{
    if (str==NULL)
        return 0;
    size_t len = strlen(str);
    if (len != 10)
        return 0;
    for (size_t i=0; i
3
дададзена
што я у вул [я] ?
дададзена аўтар Pixelchemist, крыніца
Дзякуй, я скапіяваў з гэтага пытання і не заўважыў, што гэта не будзе кампілявацца. Ці будзе абнаўленне/выправіць у секунду
дададзена аўтар simonc, крыніца

Парадак выпрабаванняў у IsValid няправільна - вы павінны праверыць NULL першы перад выклікам StrLen або разнаймення вул ,

Акрамя таго, было яшчэ некалькі памылак:

isValid needs to add a return value for the case that none of your if conditions are satisfied. I'd have expected this to generate a warning. If it didn't, compiling with warnings enabled (/W4 for MSVC, -Wall for gcc) would have flagged it.

i isn't defined so isdigit(str[i]) wouldn't compile. My updated code (below) shows how to confirm that each character in str is a digit

int isValid (const char str[])
{
    if (str==NULL)
        return 0;
    size_t len = strlen(str);
    if (len != 10)
        return 0;
    for (size_t i=0; i
3
дададзена
што я у вул [я] ?
дададзена аўтар Pixelchemist, крыніца
Дзякуй, я скапіяваў з гэтага пытання і не заўважыў, што гэта не будзе кампілявацца. Ці будзе абнаўленне/выправіць у секунду
дададзена аўтар simonc, крыніца

Улічваючы тое, што ваш IsValid сапраўды правярае, аказваецца, што яна можа быць спрошчана зусім няшмат. У прыватнасці, толькі 10-знакавая радок з лічбаў, што atoi можа пераўтварыць колькасці 1234567890, як уяўляецца, радок «1234567890», так што мы маглі б таксама проста выпрабаванне для гэтага наўпрост:

int isvalid(char const *input) { 
    return (input != NULL) && (strcmp(input, "1234567890") == 0);
}
2
дададзена
LOL. Я мяркую, што ўтрыманне незавершаны проста адцягнуўся ад аварыі ;-)
дададзена аўтар Balog Pal, крыніца

Улічваючы тое, што ваш IsValid сапраўды правярае, аказваецца, што яна можа быць спрошчана зусім няшмат. У прыватнасці, толькі 10-знакавая радок з лічбаў, што atoi можа пераўтварыць колькасці 1234567890, як уяўляецца, радок «1234567890», так што мы маглі б таксама проста выпрабаванне для гэтага наўпрост:

int isvalid(char const *input) { 
    return (input != NULL) && (strcmp(input, "1234567890") == 0);
}
2
дададзена
LOL. Я мяркую, што ўтрыманне незавершаны проста адцягнуўся ад аварыі ;-)
дададзена аўтар Balog Pal, крыніца
int isValid (const char str[])
{
  if (str == NULL) return 0;  //add this line

  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
//if (str==NULL)   //remove this line
//   return 0;     //remove this line
  if (atol(str)==1234567890)
     return 1;
}
0
дададзена
int isValid (const char str[])
{
  if (str == NULL) return 0;  //add this line

  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
//if (str==NULL)   //remove this line
//   return 0;     //remove this line
  if (atol(str)==1234567890)
     return 1;
}
0
дададзена

Сінтаксіс вы выкарыстоўвалі дазваляецца мовай пры тым разуменні, што кампілятар збіраецца ігнараваць і выкарыстоўваць паказальнік замест гэтага, таму што гэта адзінае, што гэта можа азначаць у дадзеным кантэксце:

int isValid (const char str[])

См http://c-faq.com/aryptr/aryptrparam.html .

Кампілятар апрацоўвае гэта менавіта так, як:

int isValid(const char* str)

(Таму што: Ваш сінтаксіс мяркуе, вы хочаце, каб функцыя запуску з невядомым колькасцю знакаў у стэку)

Калі вы абсалютна ўпэўнены, масіў будзе мець фіксаваны памер, і вы хочаце, каб усе прывілеі і абавязкі, якія маюць масіў, а не паказальнік, вы можаце зрабіць:

int isValid(const char str[10])//takes a copy of the array every invocation,
// I bet your next question is "why don't my changes stick"

або

int isValid(char (&str)[10])   //whee, it's an array
0
дададзена
int isValid (const char str[])
{
    if (str==NULL)
     return 0;

  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
  //if (str==NULL)   /// this should be the first check
 // return 0;      ///
  if (atol(str)==1234567890)
     return 1;
}
0
дададзена
int isValid (const char str[])
{
    if (str==NULL)
     return 0;

  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
  //if (str==NULL)   /// this should be the first check
 // return 0;      ///
  if (atol(str)==1234567890)
     return 1;
}
0
дададзена
int isValid (const char str[])
{
    if (str==NULL)
     return 0;

  int len = strlen (str);

  if (strlen (str) != 10)
     return 0;
  if (!isdigit (str[i]))
     return 0;
  //if (str==NULL)   /// this should be the first check
 // return 0;      ///
  if (atol(str)==1234567890)
     return 1;
}
0
дададзена

Пачне з дызайнам: стварэнне свайго меркавання пра NULL у выпадку. Ці з'яўляецца гэта сапраўдны уваход для гэтай функцыі? Калі няма, то не называйце гэта як, што ў асноўным, гэта парушэнне умоў.

Калі вы вырашылі NULL ў парадку, каб праверыць і IsValid дзейнічае на яго, скажам, вяртаючы значэнне 0, дадаць гэты тэст у першую чаргу. Але перад тым, што змяніць подпіс ўзяць Const сімвал * . Так, усярэдзіне яны прыкладна аднолькавыя, масіў не можа быць перададзены і на самай справе ператвараецца ў паказальнік. Але для людзей, дакументы аб намеры па-рознаму. У маёй кнізе, калі функцыя прымае масіў, ён павінен быць фактычным масіў, незалежна ад таго, што іншыя магіі мова робіць. Пры выкарыстанні паказальнік паказвае на тое, што справядлівая гульня чакаць NULL.

Пакуль вы на яго, змяніць тып якое вяртаецца значэння BOOL, як і ў предикатных функцый C ++ павінен быць. І, адпаведна, вяртаюць хлусня і праўда замест 0 і 1.

Ваш трэці, калі праверка на NULL, але ў першую вы ўжо назвалі StrLen. Перамясціць яго ўверх, і парушэнне правоў доступу сыдзе.

Крама LEN ў сопзЬ міжнар ці, дакладней, у сопзЬ аўто. Гэта сапраўды будзе size_t або без знака нешта, але астатняя частка кода не тычыцца. Затым выкарыстоўвайце, што Len канстанта, а не выклікаць STRLEN зноў.

Я не атрымліваю другое выпрабаванне, бо там няма, няма, я вакол, так што не варта нават скампіляваць.

0
дададзена

Пачне з дызайнам: стварэнне свайго меркавання пра NULL у выпадку. Ці з'яўляецца гэта сапраўдны уваход для гэтай функцыі? Калі няма, то не называйце гэта як, што ў асноўным, гэта парушэнне умоў.

Калі вы вырашылі NULL ў парадку, каб праверыць і IsValid дзейнічае на яго, скажам, вяртаючы значэнне 0, дадаць гэты тэст у першую чаргу. Але перад тым, што змяніць подпіс ўзяць Const сімвал * . Так, усярэдзіне яны прыкладна аднолькавыя, масіў не можа быць перададзены і на самай справе ператвараецца ў паказальнік. Але для людзей, дакументы аб намеры па-рознаму. У маёй кнізе, калі функцыя прымае масіў, ён павінен быць фактычным масіў, незалежна ад таго, што іншыя магіі мова робіць. Пры выкарыстанні паказальнік паказвае на тое, што справядлівая гульня чакаць NULL.

Пакуль вы на яго, змяніць тып якое вяртаецца значэння BOOL, як і ў предикатных функцый C ++ павінен быць. І, адпаведна, вяртаюць хлусня і праўда замест 0 і 1.

Ваш трэці, калі праверка на NULL, але ў першую вы ўжо назвалі StrLen. Перамясціць яго ўверх, і парушэнне правоў доступу сыдзе.

Крама LEN ў сопзЬ міжнар ці, дакладней, у сопзЬ аўто. Гэта сапраўды будзе size_t або без знака нешта, але астатняя частка кода не тычыцца. Затым выкарыстоўвайце, што Len канстанта, а не выклікаць STRLEN зноў.

Я не атрымліваю другое выпрабаванне, бо там няма, няма, я вакол, так што не варта нават скампіляваць.

0
дададзена