views:

363

answers:

4

I'm trying to pass three parameters to my write() function:

write(fd, "C,1,1\r\n", 7);

This works fine. But I would like to take a parameter and pass it to the command portion to make it dynamic:

write(fd, N, 4);

I'm not familiar with c++ types, but it keeps asking for a type of "const void*" I've been able to convert my variable, N, to a couple different formats hoping one would be easier to convert. This is what I have tried:

const fmx::FixPt&  outValue = dataVect.AtAsNumber(3);
const double  N = outValue.AsLong();

double  N = outValue.AsLong();

So double and const double(*which might be pretty much the same thing... I don't know c++ very well)

I could also leave it as just:

const fmx::FixPt&  outValue = dataVect.AtAsNumber(3);
write(fd, outValue, 4);

but I thought asking everyone how to convert a double would be much better than trying to explain or figure out something as unique as type const fmx::FixPt&...

*I also tried:

write(fd, &N, 4);

which only gets rid of my error, but still doesn't work.

So, is it even possible to convert to a type of "const void*"?

Thank you very much!

Here is code:

const fmx::FixPt& outValue = dataVect.AtAsNumber(3);
double  N = outValue.AsLong();

int fd;
struct termios options;
fd=open("/dev/tty.KeySerial1", O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(fd, F_SETFL, 0);
tcgetattr(fd,&options);
options.c_ispeed=57600;
options.c_ospeed=57600;
options.c_cflag |= (CLOCAL | CREAD);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_cflag &= ~CSTOPB;
options.c_lflag &= ~ECHO;
options.c_oflag &= ~ECHO;
options.c_oflag &= ~OPOST;
options.c_cflag |= CS8;
options.c_cflag |= CRTSCTS;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] =10;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&options);


if( tempText->Assign("2"), *tempText == direction ) {
 write(fd, "C,1,2\r\n", 7);//Direction
}else{
 write(fd, "C,1,1\r\n", 7);//Direction
}

if( tempText->Assign("1"), *tempText == speed ) {
 write(fd, "C,2,1\r\n", 7);//Speed
} else if( tempText->Assign("2"), *tempText == speed ) {
 write(fd, "C,2,2\r\n", 7);//Speed
} else if( tempText->Assign("3"), *tempText == speed ) {
 write(fd, "C,2,3\r\n", 7);//Speed
} else if( tempText->Assign("4"), *tempText == speed ) {
 write(fd, "C,2,4\r\n", 7);//Speed
} else if( tempText->Assign("5"), *tempText == speed ) {
 write(fd, "C,2,5\r\n", 7);//Speed
} else if( tempText->Assign("6"), *tempText == speed ) {
 write(fd, "C,2,6\r\n", 7);//Speed
} else if( tempText->Assign("7"), *tempText == speed ) {
 write(fd, "C,2,7\r\n", 7);//Speed
} else if( tempText->Assign("8"), *tempText == speed ) {
 write(fd, "C,2,8\r\n", 7);//Speed
} else if( tempText->Assign("9"), *tempText == speed ) {
 write(fd, "C,2,9\r\n", 7);//Speed
} else if( tempText->Assign("10"), *tempText == speed ) {
 write(fd, "C,2,10\r\n", 8);//Speed
} else if( tempText->Assign("11"), *tempText == speed ) {
 write(fd, "C,2,11\r\n", 8);//Speed
} else if( tempText->Assign("12"), *tempText == speed ) {
 write(fd, "C,2,12\r\n", 8);//Speed
} else if( tempText->Assign("13"), *tempText == speed ) {
 write(fd, "C,2,13\r\n", 8);//Speed
} else if( tempText->Assign("14"), *tempText == speed ) {
 write(fd, "C,2,14\r\n", 8);//Speed
} else if( tempText->Assign("15"), *tempText == speed ) {
 write(fd, "C,2,15\r\n", 8);//Speed
} else if( tempText->Assign("16"), *tempText == speed ) {
 write(fd, "C,2,16\r\n", 8);//Speed
} else if( tempText->Assign("17"), *tempText == speed ) {
 write(fd, "C,2,17\r\n", 8);//Speed
}



if(tempText->Assign("1"), *tempText == length){
 write(fd, "C,3,", 4);
 write(fd, "1", 1);
 write(fd, "\r\n", 2);
} else if(tempText->Assign("2"), *tempText == length){
 write(fd, "C,3,", 4);
 write(fd, "10", 2);
 write(fd, "\r\n", 2);
} else if(tempText->Assign("3"), *tempText == length){
 write(fd, "C,3,", 4);
 write(fd, "100", 3);
 write(fd, "\r\n", 2);
} else if(tempText->Assign("4"), *tempText == length){

 write(fd, "C,3,", 4);
 write(fd, N, 4);
 write(fd, "\r\n", 2);
}


close(fd);

error: cannot convert 'double' to 'const void*' for argument '2' to 'ssize_t write(int, const void*, size_t)'

+7  A: 

The write command just takes an blob of data and writes to the file descriptor. So, if you wanted to write the binary data held in your double, you would do something like:

write(fd, &N, sizeof(double));

Note that this write the binary data, not the human-readable ASCII data to your file descriptor. This can be dangerous, since the data is stored in the local architecture's byte order, but that may not be a concern depending on your application.

Normally, in C++, you would use the iostream operators:

double N = 0.0;

// write data to file
ofstream out("myfile", ofstream::binary);
out << N;
out.close();

// read data back
ifstream in("myfile", ifstream::binary);
in >> N;
in.close();

The stream operators are overloaded to take many kinds of arguments, including strings:

out << "hello world: " << 42 << endl;
jheddings
+1  A: 

The write() function's second parameter is a pointer to a buffer (an array of bytes) and the third parameter is the size of that buffer. So, you need to somehow get an array of bytes that you want to write out to that file.

Your "solution"

write(fd, &N, 4);

will work if N is something that is 4 bytes long. However, it seems like that's not what you want.

It's not clear from your question exactly what it is that you are trying to accomplish. Do you want to write a string? Then you need to convert N to a string, and pass the address of that string's first byte to write.

Kristopher Johnson
Thank you, sorry I should have added more info.I have a if/else if statement that is checking the length:... else if(tempText->Assign("4"), *tempText == length){ ...So I know 4 is correct(I'm passing 1000)My working example: write(fd, "C,1,1\r\n", 7);It does look like a string to me, but it keeps saying "unable to convert _____ to 'const void*"Why is it asking for 'const void*' it looks like a string...*side note, I tried doing const void* tester = "1000"; and it worked...so 'const void*?Thanks again!
Pfeffer
In C, a string pointer such as `"C,1,1,\r\n"` (which is of type `const char *`) will be automatically converted to `void *`. However in C++, you need to explicitly cast with `(const void *)"C,1,1,\r\n"`. Note that before casting like this you still have to get it in the format you want!
bdonlan
And in C++, you would really want to do a `static_cast<const void*>(data)`, instead of a C-style cast operation.
jheddings
A: 

From your working example, it looks like write takes a const char* as it's second parameter, and the length (number of characters in the const char*) as the 3rd.

so write(fd, "C,1,1\r\n", 7); is passing a const char* that points to "C,1,1\r\n", which is 7 characters long.

If you want to pass in a variable instead of the hardcoded "C,1,1\r\n", then you want to do the following:

int someNum = 7; // example variable

const int BUFFERSIZE = 256;
char strBuffer[BUFFERSIZE];
snprintf( strBuffer, BUFFERSIZE, "whatever you like, even a number: %d\n\r", someNum );
write( fd, str, BUFFERSIZE );
KSchmidt
Bear in mind that _snprintf_s() is not a standard function. It exists in Visual C++, and to the best of my knowledge nowhere else. If you're using any other compiler, you need to use sprintf() or that compiler's specific functions. If you are using Visual C++, _snprintf_s() is safer to use than sprintf().
David Thornley
Thanks David, I've updated the example with a portable safe version of sprintf.
KSchmidt
+1  A: 

It looks to me as if your problem is with conversion from a double to a string. I take it that, if N has the value 2000, you want to write out the characters '2', '0', '0', and '0', rather than the internal representation of 2000.0.

Actually, I see you using a function outValue.AsLong(), which I would expect to return a long value (which is an integer) instead of a double value (which is floating point), and it'll be more convenient to deal with an integer in this case. In this case, double and long are data types.

Converting numbers to strings is a little awkward in C, and is often done with the sprintf() function. It's a bit tricky. First, you have to specify an array of char to write the string into. Make sure it's big enough for the biggest number you're going to have, and add one because sprintf() writes one more character to mark the end of the string. (Most C string functions do.) Then call sprintf with it. Let's go through this.

char string_value[5];  /* we're assuming the number is always between 0 and 9999 */
long long_value = outValue.asLong();
sprintf(string_value, "%04ld", long_value);
write (fd, string_value, 4);

To explain some of these: We used 5 characters for string_value, since we need the number of characters plus 1. We get the value into long_value, and then use the sprintf() function to put the value into string_value. The first parameter of sprintf() is the memory area where the result goes, the second is the format string, and the following are the values you're putting into the string. In the format string, the '%' means it's going to describe a field, the '0' means to zero-fill the result, the '4' means to use at least four characters, and the "ld" means you're passing in a long value.

David Thornley
This worked perfectly! Thank you very much!
Pfeffer