char * 与 string 类型相互转换方法--Linux C/C++

本文介绍如何在C++中将C风格的字符串(如char*和char数组)转换为string类型,以及如何从string类型获取C风格的字符串。包括直接类型转换和使用string的c_str()方法。

1:对于C风格的字符串比如char*,char str[],转换为 string

         char * 和char str[]类型可以直接转换为string 类型;

          即,在char * chstr,

                      char arstr[]

                      string str=chstr;或者是string str=arstr;可以直接进行赋值。

2:对于string 转换为char *

     string提供一个方法可以直接返回字符串的首指针地址即:string.c_str();

     比如:string str="Hi Cpp";转换为char * 类型;

     const char * mystr=str.c_str();  注意要加上const.

 

      例外有个方法有点浪费内存:

     string str="woshi";

     char * pstr=new char [str.length()+1];

     strcat(pstr,str);

 

 

22:19:28: 为项目keypad执行步骤 ... 22:19:28: 正在启动 "/usr/bin/make" clean rm -f moc_predefs.h rm -f moc_keytest.cpp rm -f ui_keytest.h rm -f keytest.o main.o moc_keytest.o rm -f *~ core *.core 22:19:28: 进程"/usr/bin/make"正常退出。 22:19:28: 配置没有改变, 跳过 qmake 步骤。 22:19:28: 正在启动 "/usr/bin/make" /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/uic ../keyScan/keytest.ui -o ui_keytest.h /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-buildroot-linux-gnu-g++ -c -pipe -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 --sysroot=/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot -Wall -Wextra -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../keyScan -I. -I../keyScan -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/opencv4 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/mkspecs/devices/linux-buildroot-g++ -o keytest.o ../keyScan/keytest.cpp ../keyScan/keytest.cpp: 在构造函数‘Keytest::Keytest(QWidget*)’中: ../keyScan/keytest.cpp:161:13: 警告: 语句不起作用 [-Wunused-value] 161 | ui->mainLayout; | ~~~~^~~~~~~~~~ ../keyScan/keytest.cpp: 在函数‘char* scan_devices()’中: ../keyScan/keytest.cpp:147:17: 警告: ignoring return value of ‘int asprintf(char**, const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 147 | asprintf(&filename, "%s/%s%d", | ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ 148 | DEV_INPUT_EVENT, EVENT_DEV_NAME, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 149 | devnum); | ~~~~~~~ ../keyScan/keytest.cpp: 在成员函数‘void Keytest::keyEvent()’中: ../keyScan/keytest.cpp:424:26: 警告: ignoring return value of ‘ssize_t write(int, const void*, size_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 424 | write(g_igpiofd,SYSFS_GPIO_LED_VAL_H,sizeof(SYSFS_GPIO_LED_VAL_H)); // | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../keyScan/keytest.cpp:426:27: 警告: ignoring return value of ‘int system(const char*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 426 | system("echo 1 > value"); | ~~~~~~^~~~~~~~~~~~~~~~~~ ../keyScan/keytest.cpp:431:26: 警告: ignoring return value of ‘ssize_t write(int, const void*, size_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 431 | write(g_igpiofd,SYSFS_GPIO_LED_VAL_L,sizeof(SYSFS_GPIO_LED_VAL_L)); // | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../keyScan/keytest.cpp:433:27: 警告: ignoring return value of ‘int system(const char*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 433 | system("echo 0 > value"); | ~~~~~~^~~~~~~~~~~~~~~~~~ ../keyScan/keytest.cpp: 在构造函数‘Keytest::Keytest(QWidget*)’中: ../keyScan/keytest.cpp:127:37: 警告: ‘%s’ directive output may be truncated writing up to 255 bytes into a region of size 53 [-Wformat-truncation=] 127 | "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name); | ^~ In file included from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/stdio.h:906, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/cstdio:42, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/ext/string_conversions.h:43, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/bits/basic_string.h:3968, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/string:53, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore/qbytearray.h:52, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore/qstring.h:50, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore/qobject.h:47, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets/qwidget.h:45, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets/qdialog.h:44, from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets/qmessagebox.h:45, from ../keyScan/keytest.cpp:3: 在函数‘int snprintf(char*, size_t, const char*, ...)’中, 内联自‘char* scan_devices()’于 ../keyScan/keytest.cpp:126:11, 内联自‘Keytest::Keytest(QWidget*)’于 ../keyScan/keytest.cpp:184:33: /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/bits/stdio2.h:54:35: 附注: ‘__builtin_snprintf’ output between 12 and 267 bytes into a destination of size 64 54 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | __glibc_objsize (__s), __fmt, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 | __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~ /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-buildroot-linux-gnu-g++ -c -pipe -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 --sysroot=/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot -Wall -Wextra -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../keyScan -I. -I../keyScan -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/opencv4 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/mkspecs/devices/linux-buildroot-g++ -o main.o ../keyScan/main.cpp /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-buildroot-linux-gnu-g++ -pipe -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 --sysroot=/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot -Wall -Wextra -dM -E -o moc_predefs.h /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/mkspecs/features/data/dummy.cpp /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/moc -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --include /home/zpl/桌面/build-keypad-OK3562-Debug/moc_predefs.h -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/mkspecs/devices/linux-buildroot-g++ -I/home/zpl/桌面/keyScan -I/home/zpl/桌面/keyScan -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/opencv4 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/aarch64-buildroot-linux-gnu -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include/c++/12.3.0/backward -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/lib/gcc/aarch64-buildroot-linux-gnu/12.3.0/include -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/lib/gcc/aarch64-buildroot-linux-gnu/12.3.0/include-fixed -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/include -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include ../keyScan/keytest.h -o moc_keytest.cpp /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-buildroot-linux-gnu-g++ -c -pipe -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 --sysroot=/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot -Wall -Wextra -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../keyScan -I. -I../keyScan -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/opencv4 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5 -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtWidgets -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/libdrm -I. -I/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/mkspecs/devices/linux-buildroot-g++ -o moc_keytest.o moc_keytest.cpp /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-buildroot-linux-gnu-g++ --sysroot=/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot -o fltest_qt_keypad keytest.o main.o moc_keytest.o -latomic -L/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libQt5Widgets.so /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libQt5Gui.so /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libQt5Core.so -lmali-hook -lmali-hook-injector -lmali -ldrm -lwayland-client -lwayland-server -lpthread -lrt -lpthread -ldl 22:19:33: 进程"/usr/bin/make"正常退出。 22:19:33: Elapsed time: 00:05.
最新发布
08-31
<think> 我们正在处理一个关于编译警告的问题。用户提到了几种警告类型:语句不起作用、忽略函数返回值、格式截断。我们需要逐一分析这些警告的原因并提供解决方案。 1. **语句不起作用(Statement with no effect)**: 这种警告通常出现在代码中写了一个表达式,但没有将其结果赋值给任何变量,也没有用于条件判断等。例如,在C/C++中,你可能会写: x + 5; // 这个表达式的值没有被使用 或者是一个函数调用但没有使用其返回值,并且这个函数被标记为`warn_unused_result`属性(例如,某些系统函数如`write`)时,也会产生类似警告。 解决方法: - 如果确实不需要返回值,可以显式地将结果强制换为void:`(void)function_call();` - 如果是无用的表达式语句,直接删除。 2. **忽略函数返回值(Ignoring return value)**: 这个警告是因为调用了一个有返回值的函数,但是没有检查或使用这个返回值。特别是一些重要的系统函数(如`read`, `scanf`等),忽略返回值可能会导致程序逻辑错误。 解决方法: - 如果返回值确实需要检查(比如错误处理),则添加错误处理代码。 - 如果确定可以忽略,可以显式地换为void:`(void)function_call();` (这在C/C++中是常见的做法) 3. **格式截断(Format truncation)**: 这个警告通常发生在使用`printf`系列函数时,格式字符串指定的输出长度可能超过了提供的缓冲区大小。例如: char buf[10]; snprintf(buf, sizeof(buf), "This is a long string: %s", long_str); 如果`long_str`很长,那么写入`buf`的字符串会被截断,但编译器可能会警告你截断的发生。 解决方法: - 确保目标缓冲区足够大以容纳格式化后的字符串- 如果使用`sprintf`,考虑改用安全版本`snprintf`(如果已经是,那么需要确保第二个参数(缓冲区大小)足够大,或者接受截断并忽略警告)。 - 如果确实允许截断,并且使用了`snprintf`,那么可以通过编译器选项来关闭特定警告(不推荐),或者使用`#pragma`忽略该特定位置的警告。 除了针对每种警告的解决方法,还有一些通用的步骤: 1. **检查代码**:定位到产生警告的代码行(编译器通常会给出文件名和行号),然后根据上述方法进行修改。 2. **编译器选项**:有时候可以通过调整编译器选项来更细致地控制警告。比如,GCC中可以使用`-Wno-unused-result`来关闭忽略返回值的警告,但建议只在确实不需要返回值时使用,并且最好在代码中显式换。 3. **静态代码分析工具**:使用如Clang静态分析器、Cppcheck等工具可以帮助发现更多潜在问题。 4. **代码审查**:对于反复出现的警告,进行代码审查以确保代码质量。 下面针对每种情况给出代码示例: **情况1:语句不起作用** ```c // 原代码 int x = 10; x + 5; // 警告:语句不起作用 // 修改:删除该语句或使用它 ``` **情况2:忽略函数返回值** ```c // 原代码 FILE *fp = fopen("file.txt", "r"); fopen_s(&fp, "file.txt", "r"); // 如果使用fopen_s,它返回errno_t,但是这里没有检查 // 修改:检查返回值 if (fopen_s(&fp, "file.txt", "r") != 0) { // 错误处理 } // 或者,如果确定要忽略返回值: (void)fopen_s(&fp, "file.txt", "r"); ``` **情况3:格式截断** ```c // 原代码 char buf[10]; snprintf(buf, sizeof(buf), "This is a long string: %s", long_str); // 如果long_str很长,会截断,编译器可能警告 // 修改:增大缓冲区大小,或者如果允许截断,则忽略警告(但最好确保缓冲区足够) char buf[100]; // 增大缓冲区 // 或者,如果无法增大缓冲区,且截断是可接受的,可以添加以下编译指示屏蔽该警告(GCC): #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" snprintf(buf, sizeof(buf), "%s", long_str); #pragma GCC diagnostic pop ``` 最后,建议不要轻易全局关闭警告,因为警告往往指示了潜在的问题。应该逐条分析并采取合适的措施。 如果用户提供了具体的警告信息或代码片段,可以给出更具体的建议。 生成相关问题: 1. 如何全局关闭特定类型的编译警告? 2. 除了修改代码,还有哪些方法可以处理编译警告? 3. 如何提升代码质量以减少编译警告? 4. 在团队开发中,如何统一处理编译警告的策略? </think> 针对项目(keypad)编译过程中的警告问题,我将逐步分析并提供解决方案: ### 一、三类警告的解决方法 1. **语句不起作用警告** - **原因**:存在冗余代码(如未使用的变量、无实际操作的表达式) - **解决方案**: ```c // 示例:删除无用语句 int unused_var; // 警告:变量未使用 → 删除此行 value; // 警告:纯表达式无效果 → 删除或改为赋值操作 ``` 2. **忽略函数返回值警告** - **原因**:调用了需要检查返回值的函数(如文件操作、内存分配) - **解决方案**: ```c // 修改前(忽略返回值) fopen("config.txt", "r"); // 修改后(检查返回值) FILE* fp = fopen("config.txt", "r"); if (fp == NULL) { // 错误处理 } ``` - 对于明确需要忽略的情况,可添加`(void)`强制换: ```c (void) system("clear"); // 显式忽略返回值 ``` 3. **格式截断警告** - **原因**:格式化输出(如`printf/sprintf`)可能超出缓冲区 - **解决方案**: ```c // 修改前(危险操作) char buf[10]; sprintf(buf, "%s", long_string); // 可能溢出 // 修改后(安全做法) snprintf(buf, sizeof(buf), "%s", long_string); // 自动截断 // 或增加缓冲区大小 char buf[256]; // 根据实际需求调整 ``` ### 二、通用优化措施 1. **编译器选项调整**(以GCC为例) ```bash # 显示详细警告来源 gcc -Wall -Wextra -Wpedantic -fdiagnostics-show-option # 针对性禁用特定警告(谨慎使用) gcc -Wno-unused-result -Wno-format-truncation ``` 2. **静态代码分析工具** - 使用`cppcheck`扫描: ```bash cppcheck --enable=all ./src/ ``` - 使用Clang分析器: ```bash scan-build make ``` 3. **代码规范强化** - 启用编译警告视为错误(强制解决): ```makefile CFLAGS += -Werror ``` - 添加静态断言(C11标准): ```c static_assert(sizeof(buffer) > 256, "Buffer too small!"); ``` ### 三、典型修复流程 1. **定位问题**:根据警告信息定位源码文件和行号 2. **分类处理**- 冗余代码 → 直接删除 - 返回值忽略 → 添加错误处理 - 格式截断 → 改用安全函数或扩容 3. **验证测试**:编译后运行单元测试,确保功能正常 4. **持续集成**:在构建脚本中添加静态检查步骤 > **关键建议**:优先解决**格式截断**类警告,因其可能导致内存溢出漏洞;返回值类警告涉及程序健壮性;语句无效警告可后续批量清理[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值