如何处理从main接收到的NULL.c++

How to handle NULL, which is being received from main. C++

本文关键字:c++ NULL main 何处理 处理      更新时间:2023-10-16

我是c++新手。我有一个函数叫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;
}

样本主要:

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

我得到这个:

测试

段错误

如何实现NULL。谢谢!

isValid中的测试顺序错误-您需要先测试NULL,然后调用strlen或取消对str的引用。

你还有另外两个错误:

isValid需要在不满足if条件的情况下添加返回值。我本以为这会发出警告。如果没有,编译时启用警告(MSVC的/W4, gcc的-Wall)会标记它。

i没有定义,所以isdigit(str[i])不能编译。我更新的代码(如下)显示了如何确认str中的每个字符是一个数字

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<len; i++) {
        if (!isdigit (str[i]))
            return 0;
    }
    if (atol(str)==1234567890)
        return 1;
    return 0;
}

考虑到您的isValid真正检查的内容,它似乎可以简化很多。具体来说,atoi可以转换为1234567890的所有数字的唯一10个字符字符串似乎是字符串"1234567890",所以我们不妨直接测试一下:

int isvalid(char const *input) { 
    return (input != NULL) && (strcmp(input, "1234567890") == 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;
}
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;
}

从设计开始:在这种情况下决定NULL。它是这个函数的有效输入吗?如果不是,那么不要在main中这样调用它,这违反了前提条件。

如果您决定测试NULL是可以的,并且isValid将对其进行操作,例如返回0,则首先添加该测试。但在此之前,将签名更改为const char*。是的,在内部它们是相同的,数组不能传递,真正转换为指针。但对人类来说,它记录的意图不同。在我的书中,如果函数接受一个数组,它必须是一个真正的数组,不管语言做了什么其他神奇的事情。而使用指针表示期望NULL是公平的游戏。

此时,将返回类型更改为bool,就像c++谓词函数应该的那样。相应地返回false和true,而不是0和1。

你的第三个if检查NULL,但是在第一个你已经调用了strlen。把它移上去,访问冲突就会消失。

将len存储在const int或const auto中。它实际上是size_t或unsigned什么的,但其余的代码不需要考虑。然后使用len常量,而不是再次调用strlen。

我没有得到第二个测试,因为周围没有I,所以它甚至不应该编译。

您使用的语法是语言允许的,因为编译器会忽略它并使用指针代替,因为这是它在此上下文中唯一可以表示的含义:

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