You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言:如何将char转字符串传strcpy?活动网卡接口名传strcpy失败如何解决?

C语言问题解答

问题1:单个char类型字符转字符串用于strcpy

strcpy函数要求传入的源参数是以'\0'结尾的字符串,而单个char只是一个独立字符,没有终止符,直接使用会导致strcpy读取越界(因为它会一直找'\0'直到内存里的随机位置)。这里有几种简单可靠的解决方法:

  • 方法1:手动构建长度为2的字符串数组
    直接把字符放到数组第一个位置,第二个位置手动添加终止符:

    char c = 'X';
    char str_buf[2];
    str_buf[0] = c;
    str_buf[1] = '\0'; // 必须添加终止符
    strcpy(your_dest_str, str_buf);
    
  • 方法2:用sprintf格式化生成字符串
    利用格式化函数自动生成带终止符的字符串,写法更灵活:

    char c = 'Y';
    char temp_str[2];
    sprintf(temp_str, "%c", c); // 自动在末尾补'\0'
    strcpy(your_dest_str, temp_str);
    // 也可以直接写入目标缓冲区(确保目标有足够空间)
    sprintf(your_dest_str, "%c", c);
    
  • 方法3:直接写入目标缓冲区并补终止符
    如果目标缓冲区已有预留空间,也可以这么写:

    char c = 'Z';
    char dest[2];
    dest[0] = c;
    dest[1] = '\0';
    

问题2:活动网络接口名传入后无法获取MAC地址的问题

核心原因

你用fgets读取接口名时,会把输入的换行符\n也一起读进interface数组里!比如你打印看到的interface :: wlp1s0,实际上内存里的内容是"wlp1s0\n\0",而手动写的"wlp1s0"是没有换行符的。内核的网络接口识别逻辑会把带换行的字符串当成无效接口名,所以ioctl调用失败。

解决方法

只需要在读取后移除换行符即可,这里推荐两种可靠的方式:

方式1:用strcspn快速移除换行符(最简洁)

strcspn会返回字符串中第一个匹配指定字符的位置,我们直接把这个位置设为'\0',不管有没有换行都安全:

while (fgets(interface, 100, f) != NULL) {
    // 移除换行符(包括可能的回车符)
    interface[strcspn(interface, "\n\r")] = '\0';
}

方式2:用strchr查找换行符并替换

如果需要更明确的逻辑,可以用strchr定位换行符:

while (fgets(interface, 100, f) != NULL) {
    char *newline = strchr(interface, '\n');
    if (newline != NULL) {
        *newline = '\0'; // 把换行符替换成终止符
    }
}

额外优化建议

另外注意:<linux/if.h>中定义了IFNAMSIZ(通常是16),这是内核允许的网络接口名最大长度,你可以把interface数组的长度设为IFNAMSIZ,避免不必要的内存浪费,同时防止过长的接口名导致溢出。

修改后的完整健壮代码(关键部分优化):

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <netdb.h>

#define MAX_IF_NAME_LEN IFNAMSIZ // 使用内核定义的最大接口名长度
char interface[MAX_IF_NAME_LEN] = {0};
char reader_mac[13] = {0};

int main() {
    FILE *f = popen("ip addr show | awk '/inet.*brd/{print $NF}'", "r");
    if (f == NULL) { // 检查popen是否成功
        perror("popen failed");
        return 1;
    }
    if (fgets(interface, MAX_IF_NAME_LEN, f) != NULL) {
        interface[strcspn(interface, "\n\r")] = '\0';
    }
    printf("interface :: %s\n", interface);
    pclose(f);

    struct ifreq s;
    int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (fd == -1) { // 检查socket创建是否成功
        perror("socket failed");
        return 1;
    }
    strncpy(s.ifr_name, interface, IFNAMSIZ-1); // 用strncpy更安全,防止溢出
    s.ifr_name[IFNAMSIZ-1] = '\0'; // 确保终止符存在

    if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) {
        int i;
        for (i = 0; i < 6; ++i){
            unsigned char data = s.ifr_addr.sa_data[i];
            sprintf(reader_mac+(i*2), "%02x", data);
        }
        reader_mac[12] = '\0';
        printf("reader_mac ::: %s\n",reader_mac);
    } else {
        perror("ioctl failed"); // 打印错误信息,方便调试
    }
    close(fd); // 别忘了关闭socket
    return 0;
}

内容的提问来源于stack exchange,提问作者Mahamutha M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:27:49