我在Mac Os X雪豹上使用xcode 4。 我正在尝试编写一个函数来在一个区间内生成一个随机数,除了一些数字 即:
int num=5;
random(time(NULL),1,100,&num,NULL);
这必须生成1和100之间的数字,除了5。 所以我写了这段代码:
//
// main.cpp
// CPPTest
//
// Created by Ramy Al Zuhouri on 3/7/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#include <iostream>
#include <exception>
#include <cstdarg>
#include <cstdlib>
#include <ctime>
using namespace std;
class cannotGenerate : public exception
{
virtual const char* what()
{
return "Cannot generate any number, maybe the interval is empty, or the exluding vector is too large\n";
}
};
// Random number generation
// min : min number (included)
// max : max number (included)
// seed : generator seed
// excp1 first argument of int pointers (the last must be NULL)
// the int pointers represent the numbers that must be excluded
// so that if such number is generated, it has to be generated again
int random(unsigned int seed=(unsigned int)time(NULL),int min=0,int max=RAND_MAX, int* excp1=NULL , ...)
{
// variables
int result,*ptr;
va_list vl;
static unsigned int count=0;
// instructions
srand(seed+count++);
va_start(vl,excp1);
do // this do-while has the purpose to keep generating numbers until the number is correct
{ // correct = within the [min,max] interval and not a number of the list of pointers
result=rand()%(max-min+1)+min;
ptr=excp1;
do // this do-while has the purpose to check all the va_list and to read all arguments
{ // passed to the function
if(ptr!=NULL)
{ // here there is the exception (with gdb 6.3.50) :
if(result==*ptr) // Thread 1: Program received signal: "EXC_BAD_ACCESS".
result=min-1;
ptr=va_arg(vl,int*);
}
else
{
break;
}
}while(ptr!=NULL && (result<min || result>min));
}while(result<min || result>max);
va_end(vl);
// result
return result;
}
int main (int argc, const char * argv[])
{
int excp[]={1,2,3,4};
int rand;
for(int i=0;i<100;i++)
{
rand=random((unsigned int)time(NULL),1,100,&excp[0],&excp[1],&excp[2],&excp[3],NULL);
if(rand==1 || rand==2 || rand==3 || rand==4)
{
cerr << "error" << endl;
break;
}
else
{
printf("%d\n",rand);
}
}
return 0;
}
但是对于gdb我得到了这个例外:
线程1:编程接收信号:&#34; EXC_BAD_ACCESS&#34;。
在那个块中,ptr不能为NULL,所以我无法弄清楚这个异常的原因。
答案 0 :(得分:1)
这是很多代码。试试这个:
int z = ((arc4random() % 100)+1);
if (z == 5){
[self tryAgain]
}else {
return z;
}
(用你的最大值替换100,用任意数量的排除变量替换5)
这将生成0到99之间的随机数,然后向其中添加一个。如果结果为5,则将其循环以获得不同的数字。 另外,请在代码中注意这一行:
}while(ptr!=NULL && (result<min || result>min));
是吗?小于或大于最低?
答案 1 :(得分:1)
问题是你没有在第一次运行后重置变量参数列表,所以它在NULL输入后最终指向内存导致异常(如果你很幸运)。
尝试使用以下内容随机替换内部循环(注意va_start和va_end的位置)。
do {
result=rand()%(max-min+1)+min;
va_start(vl,excp1); //note
ptr=excp1;
do
{
if(ptr!=NULL)
{
if(result==*ptr)
result=min-1;
ptr=va_arg(vl,int*);
}
else
{
break;
}
} while(ptr!=NULL && (result<min || result>min));
va_end(vl); //note
}while(result<min || result>max);