0

我是 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

分段故障

我如何实现 NULL。谢谢!

4

6 回答 6

3

测试的顺序isValid是错误的 - 你需要NULL在调用strlen或取消引用之前先测试str

您还有另外几个错误:

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

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;
}
于 2013-06-02T16:27:24.830 回答
2

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

int isvalid(char const *input) { 
    return (input != NULL) && (strcmp(input, "1234567890") == 0);
}
于 2013-06-02T16:43:48.153 回答
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
于 2013-06-02T17:36:51.673 回答
0

从设计开始:在案例中确定 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 所以它甚至不应该编译。

于 2013-06-02T16:39:54.253 回答
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;
}
于 2013-06-02T16:27:44.497 回答
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;
}
于 2013-06-02T16:27:46.413 回答