【问题标题】:Error when return a value from a function C++从函数 C++ 返回值时出错
【发布时间】:2021-09-16 11:33:04
【问题描述】:

我有这段代码,我想从主函数调用char temp() 函数。 此外,我希望 char temp() 的返回值是浮动的,因为它是一个温度值,例如:- 97.21、98.33 等

我使用显式和隐式类型转换将 buf 转换为浮点数,但这也会引发错误。 有人可以帮忙吗?

#define SERIALTERMINAL      "/dev/ttyUSB0"
#include <errno.h>
#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= CLOCAL | CREAD;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    tty.c_lflag |= ICANON | ISIG;  /* canonical input */
    tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);

    tty.c_iflag &= ~IGNCR;  /* preserve carriage return */
    tty.c_iflag &= ~INPCK;
    tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);   /* no SW flowcontrol */

    tty.c_oflag &= ~OPOST;

    tty.c_cc[VEOL] = 0;
    tty.c_cc[VEOL2] = 0;
    tty.c_cc[VEOF] = 0x04;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}


char temp()
{
    char *portname = SERIALTERMINAL;
    int fd;
    int wlen;

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    /*baudrate 115200, 8 bits, no parity, 1 stop bit */
    set_interface_attribs(fd, B115200);

    /* simple output */
    wlen = write(fd, "Hello!\n", 7);
    if (wlen != 7) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);    /* delay for output */

    unsigned char buf[83];
    /* simple canonical input */
    do {
        //unsigned char buf[83];
        unsigned char *p;
        int rdlen;

        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
            buf[rdlen] = 0;
            printf("%s", buf);
        } else if (rdlen < 0) {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        } else {  /* rdlen == 0 */
            printf("Nothing read. EOF?\n");
        }
        /* repeat read */
    } while (1);
return buf;
}

int main() {

unsigned char tem[83];
tem= temp();
printf ("%s", tem);

}

我得到的错误是-->

ser.cpp: In function ‘char temp()’:
ser.cpp:1:29: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
 #define SERIALTERMINAL      "/dev/ttyUSB0"
                             ^
ser.cpp:53:22: note: in expansion of macro ‘SERIALTERMINAL’
     char *portname = SERIALTERMINAL;
                      ^~~~~~~~~~~~~~
ser.cpp:103:8: error: invalid conversion from ‘unsigned char*’ to ‘char’ [-fpermissive]
 return buf;
        ^~~
ser.cpp:72:19: warning: address of local variable ‘buf’ returned [-Wreturn-local-addr]
     unsigned char buf[83];
                   ^~~
ser.cpp: In function ‘int main()’:
ser.cpp:109:11: error: incompatible types in assignment of ‘char’ to ‘unsigned char [83]’
 tem= temp();

【问题讨论】:

  • 如果您使用 C 语言编写,为什么要使用 C++ 编译器?
  • @n.1.8e9-where's-my-sharem。先生,我不知道自从过去 4 天以来,我一直在努力让这个工作,在学习一些东西的方式上,但从昨天开始就一直坚持下去。尝试了所有组合,但总是搞砸!可以的话请帮忙
  • 1) char temp() 被声明为返回单个字符,而您正在返回一个数组。 2)。返回(指向)本地数组是一个坏主意。 3) 你不能重新分配一个数组。
  • @jkb 所以我使用了 char temp 并做了所有相关的更改,但我仍然遇到各种错误。例如这个额外的错误 ---> ser.cpp:60:17: error: invalid conversion from ‘int’ to ‘char’ [-fpermissive] return -1;
  • 由于您显然是在编写 C 而不是 C++ 代码,请考虑将您的函数签名更改为 void temp(char *buf) 并将其称为 temp(tmp),这将允许您将字符串转换为 tmp 而无需返回一个数组,没有内存分配。另外,你应该看看你的 do...while 循环——它永远不会结束。

标签: c++ casting return return-type


【解决方案1】:

所以我认为你在这里有很多问题。

第一个错误很容易解决。只需将char *portname = SERIALTERMINAL; 替换为char portname[] = SERIALTERMINAL;,它就会消失。

第二个错误是由于您将temp 定义为char temp() - 这意味着它返回单个char 而buf 是char 的数组。将temp 的定义更改为char * temp(注意其中的*)应该可以解决这个问题。

第三个错误更成问题。基本上,buf 使用的内存是函数堆栈的一部分,它只有在函数结束之前才“有效”。所以当你返回它时,你基本上是给调用者一个指向不再有效的内存的指针。为了解决这个问题,您必须动态分配内存(然后确保它也被释放)。一般来说,最好不要像这里那样将数组作为函数堆栈的一部分,因为它们往往很容易受到溢出攻击。

最后,最后一个错误应该通过修复更改为第二个错误。但请注意,您在这里所做的是复制函数返回的 pointer,而不是指针指向的 content。解决这个问题的最简单方法是将tmp 的定义更改为char *tmp; - 它将保存temp 返回的指针。

【讨论】:

  • 由于return buf; 无法访问,所以buf 是否是本地缓冲区并不重要;)
  • 是和不是。确实,现在之前的循环没有退出条件,但这很重要,原因有两个:1.循环的代码可能会改变并暴露问题,2.仍然是编译器错误。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多