实用的嵌入式 C 程序!建议收藏

news2025/1/11 12:47:40

在学习和工作开发的时候,经常需要使用到各种各样不太常用的操作,这种情况一般是自己手动写一些小程序来处理。因为它们不太常用,所以经常用了又没保存,等到下一次在使用的时候又需要重写,这样的非常浪费时间和精力。

所以想在这里统一记录一下,以备下次重新使用。代码以实用为主,如果缺陷,欢迎指出。

1、十六进制字符转整型数字

功能:将16进制的字符串转换为10进制的数字。我是没有找到相应的库函数,所以参考网上的代码自己手动写了个函数来实现。

常用的函数有atoi,atol,他们都是将10进制的数字字符串转换为int或是long类型,所以在有些情况下不适用。

/*=============================================================================
#    FileName: hex2dec.cpp
#    Desc: Convert a hex string to a int number
#    Author: Caibiao Lee
#   Version: 
#   LastChange: 2018-11-26 
#   History:
=============================================================================*/
 
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <ctype.h>
 
int c2i(char ch)  
{  
    // 如果是数字,则用数字的ASCII码减去48, 如果ch = '2' ,则 '2' - 48 = 2  
    if(isdigit(ch))  
       return ch - 48;  
 
    // 如果是字母,但不是A~F,a~f则返回  
    if( ch < 'A' || (ch > 'F' && ch < 'a') || ch > 'z' )  
      return -1;  
 
    // 如果是大写字母,则用数字的ASCII码减去55, 如果ch = 'A' ,则 'A' - 55 = 10  
    // 如果是小写字母,则用数字的ASCII码减去87, 如果ch = 'a' ,则 'a' - 87 = 10  
    if(isalpha(ch))  
       return isupper(ch) ? ch - 55 : ch - 87;  
 
    return -1;  
} 
 
int hex2dec(char *hex)  
{  
   int len;  
   int num = 0;  
   int temp;  
   int bits;  
   int i;  
   char str[64] = {0};
 
 if(NULL==hex)
 {
  printf("input para error \n");
  return 0;
 }
 
 
 if(('0'==hex[0])&&(('X'==hex[1])||('x'==hex[1])))
 {
  strcpy(str,&hex[2]);
 }else
 {
  strcpy(str,hex);
 }
 
 printf("input num = %s \n",str);
 
 // 此例中 str = "1de" 长度为3, hex是main函数传递的  
 len = strlen(str);  
 
 for (i=0, temp=0; i<len; i++, temp=0)  
 {  
    // 第一次:i=0, *(str + i) = *(str + 0) = '1', 即temp = 1  
    // 第二次:i=1, *(str + i) = *(str + 1) = 'd', 即temp = 13  
    // 第三次:i=2, *(str + i) = *(str + 2) = 'd', 即temp = 14  
    temp = c2i( *(str + i) );  
    // 总共3位,一个16进制位用 4 bit保存  
    // 第一次:'1'为最高位,所以temp左移 (len - i -1) * 4 = 2 * 4 = 8 位
    // 第二次:'d'为次高位,所以temp左移 (len - i -1) * 4 = 1 * 4 = 4 位
    // 第三次:'e'为最低位,所以temp左移 (len - i -1) * 4 = 0 * 4 = 0 位
    bits = (len - i - 1) * 4;  
    temp = temp << bits;  
 
    // 此处也可以用 num += temp;进行累加  
    num = num | temp;  
  }  
 
  // 返回结果  
  return num;  
}  
 
int main(int argc, char **argv)
{
 int l_s32Ret = 0;
 
 if(2 != argc)
 {
  printf("=====ERROR!======\n");
  printf("usage: %s Num \n", argv[0]);
  printf("eg 1: %s 0x400\n", argv[0]);
  return 0;
 }
 
 l_s32Ret = hex2dec(argv[1]);
 printf("value hex = 0x%x \n",l_s32Ret);
 printf("value dec = %d \n",l_s32Ret);
 return 0;
}

运行结果:

biao@ubuntu:~/test/flash$ ./a.out 0x400
input num = 400 
value hex = 0x400 
value dec = 1024 
biao@ubuntu:~/test/flash$ 

2、字符串转整型

功能:将正常输入的16进制或是10进制的字符串转换为int数据类型。

/*=============================================================================
#   FileName: hex2dec.cpp
#   Desc: Convert a hex/dec string to a int number
#   Author: Caibiao Lee
#   Version: 
#   LastChange: 2018-12-03 
#   History:
=============================================================================*/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <ctype.h>
 
int String2int(char *strChar)
{
 int len=0;
 const char *pstrCmp1="0123456789ABCDEF";
 const char *pstrCmp2="0123456789abcdef";
 
 char *pstr=NULL;
 int uiValue=0;
 int j=0; 
 unsigned int t=0;
 int i=0;
 if(NULL==strChar)
  return -1;
 if(0>=(len=strlen((const char *)strChar)))
  return -1;
 if(NULL!=(pstr=strstr(strChar,"0x"))||NULL!=(pstr=strstr(strChar,"0X")))
 {
  pstr=(char *)strChar+2;
  
  if(0>=(len=strlen((const char *)pstr)))
   return -1;
  for(i=(len-1);i>=0;i--)
  {
   if(pstr[i]>'F')
   {
    for(t=0;t<strlen((const char *)pstrCmp2);t++)
    { 
     if(pstrCmp2[t]==pstr[i])
      uiValue|=(t<<(j++*4));
    }
   }
   else
   {
    for(t=0;t<strlen((const char *)pstrCmp1);t++)
    { 
     if(pstrCmp1[t]==pstr[i])
      uiValue|=(t<<(j++*4));
    }
   }
  }
 }
 else
 {
  uiValue=atoi((const char*)strChar);
 }
 return uiValue;
}
 
int main(int argc, char **argv)
{
 int l_s32Ret = 0;
  
 if(2!=argc)
 {
  printf("=====ERROR!======\n");
  printf("usage: %s Num \n", argv[0]);
  printf("eg 1: %s 0x400\n", argv[0]);
  return 0;
 }
 l_s32Ret = String2int(argv[1]);
 printf("value hex = 0x%x \n",l_s32Ret);
 printf("value dec = %d \n",l_s32Ret);
 return 0;
}

3、创建文件并填充固定数据

功能:创建固定大小的一个文件,并且把这个文件填充为固定的数据。

/*=============================================================================
#     FileName: CreateFile.cpp
#         Desc: 创建固定大小的文件,然后填充固定的数据
#       Author: Caibiao Lee
#      Version: 
#   LastChange: 2018-11-26 
#      History:
=============================================================================*/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <ctype.h>
 
//#define FILL_DATA_VALUE  0xff
#define FILL_DATA_VALUE  0x30 //char 0
 
int c2i(char ch)  
{  
    if(isdigit(ch))  
            return ch - 48;  
 
    if( ch < 'A' || (ch > 'F' && ch < 'a') || ch > 'z' )  
            return -1;  
 
    if(isalpha(ch))  
            return isupper(ch) ? ch - 55 : ch - 87;  
 
    return -1;  
} 
 
int hex2dec(char *hex)  
{  
    int len;  
    int num = 0;  
    int temp;  
    int bits;  
    int i;  
    char str[64] = {0};
 
 if(NULL==hex)
 {
  printf("input para error \n");
  return 0;
 }
 
 if(('0'==hex[0])&&(('X'==hex[1])||('x'==hex[1])))
 {
  strcpy(str,&hex[2]);
 }else
 {
  strcpy(str,hex);
 }
 
 printf("input num = %s \n",str);
 
    len = strlen(str);  
 
    for (i=0, temp=0; i<len; i++, temp=0)  
    {  
            temp = c2i( *(str + i) );  
 
            bits = (len - i - 1) * 4;  
            temp = temp << bits;  
 
            num = num | temp;  
    }  
    return num;  
}  
 
int main(int argc, char **argv)
{
 FILE *l_pFile = NULL;
 int  l_s32Rest = 0;
 unsigned int l_WriteLen = 0;
 unsigned int l_FileLen = 0;
 unsigned char TempData[1024] = {FILL_DATA_VALUE};
 
 if(3!=argc)
 {
  printf("usage: %s FileName  FileLen \n ", argv[0]);
  printf("eg: %s ./Outfile.bin 0x400 \n ", argv[0]);
  return 0;
 };
 
 const char *l_pFileName = argv[1];
 if(NULL==l_pFileName)
 {
  printf("input file name is NULL \n");
  return -1;
 }
 
 if(('0'==argv[2][0])&&(('X'==argv[2][1])||('x'==argv[2][1])))
 {
  l_FileLen = hex2dec(argv[2]);
  
 }else
 {
  l_FileLen = atoi(argv[2]);
 }
 
 printf("Need To Write Data Len %d \n",l_FileLen);
 printf("Fill Data Vale = 0x%x \n",FILL_DATA_VALUE);
 
 for(int i=0;i<1024;i++)
 {
  TempData[i] = FILL_DATA_VALUE;
 }
 
 
 l_pFile = fopen(l_pFileName,"w+");
 if(l_pFile==NULL)
 {
  printf("open file %s error \n",l_pFileName);
  return -1;
 }
 
 
 while(l_WriteLen<l_FileLen)
 {
  if(l_FileLen<1024)
  {
   l_s32Rest = fwrite(TempData,1,l_FileLen,l_pFile);
   
  }
  else
  {
   l_s32Rest = fwrite(TempData,1,1024,l_pFile);
  }
 
  if(l_s32Rest <= 0)
  {
   break;
  };
 
  l_WriteLen +=l_s32Rest; 
 }
 
 if(NULL!=l_pFile)
 {
  fclose(l_pFile);
  l_pFile = NULL;
 }
 
 return 0;
 
}

运行结果:

biao@ubuntu:~/test/flash$ gcc CreateFile.cpp 
biao@ubuntu:~/test/flash$ ls
a.out  CreateFile.cpp  hex2dec.cpp  main.cpp  out.bin
biao@ubuntu:~/test/flash$ ./a.out ./out.bin 0x10
input num = 10 
Need To Write Data Len 16 
Fill Data Vale = 0x30 
biao@ubuntu:~/test/flash$ ls
a.out  CreateFile.cpp  hex2dec.cpp  main.cpp  out.bin
biao@ubuntu:~/test/flash$ vim out.bin 
  1 0000000000000000                                     

4、批量处理图片

功能:批处理将图片前面固定的字节数删除。

/*=============================================================================
#     FileName: CutFile.cpp
#         Desc: 批量处理,将图片的前面固定字节删除
#       Author: Caibiao Lee
#      Version: 
#   LastChange: 2018-11-26 
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
 
 
#define START_READ_POSITION  128
#define PHOTO_START_TIME  83641
//l_s32PhotoTime = 92809;
 
int Cut_file(char * InputFile)
{
 FILE *l_pFileInput = NULL;
 FILE *l_pFileOutput = NULL;
 char l_ars8OutputName[128] = {0};
 unsigned char l_arru8TempData[1024] = {0};
 int l_s32Ret = 0;
 static unsigned int ls_u32Num = 0;
 
 
 if(NULL== InputFile) 
 {
  goto ERROR;
 }
 
 //sprintf(l_ars8OutputName,"./outfile/_%s",&InputFile[8]);
 sprintf(l_ars8OutputName,"./outfile/00%d.jpg",ls_u32Num++);
 
 //printf("out file name %s \n",l_ars8OutputName);
 
 l_pFileInput = fopen(InputFile,"rb+");
 if(NULL==l_pFileInput)
 {
  printf("input file open error\n");
  goto ERROR;
 }
 
 l_pFileOutput = fopen(l_ars8OutputName,"w+");
 if(NULL==l_pFileOutput)
 {
  printf("out file open error\n");
  goto ERROR;
 }
 
 fseek(l_pFileInput,START_READ_POSITION,SEEK_SET);
 
 while(!feof(l_pFileInput))
 {
  l_s32Ret = fread(l_arru8TempData,1,1024,l_pFileInput);
  if(l_s32Ret<0)
  {
   break;
  }
 
  l_s32Ret = fwrite(l_arru8TempData,1,l_s32Ret,l_pFileOutput);
  if(l_s32Ret<0)
  {
   break;
  }
 }
 
ERROR:
 if(NULL!=l_pFileOutput)
 {
  fclose(l_pFileOutput);
  l_pFileOutput =NULL;
 };
 
 if(NULL !=l_pFileInput);
 {
  fclose(l_pFileInput);
  l_pFileInput =NULL;
 }
}
 
int main(void)
{
 char l_arrs8InputName[128] = {0};
 char l_s8PhotoChannel = 0;
 int  l_s32PhotoTime = 0;
 
 l_s8PhotoChannel = 3;
 l_s32PhotoTime = PHOTO_START_TIME;
 
 /**从第一通道开始**/
 for(int j=1;j<l_s8PhotoChannel;j++)
 {
 
  for(int i=l_s32PhotoTime;i<235959;i++)
  {
   memset(l_arrs8InputName,0,sizeof(l_arrs8InputName));
   sprintf(l_arrs8InputName,"./image/%dY%06d.jpg",j,i);
 
   if(0==access(l_arrs8InputName,F_OK))
   {
    printf("%s\n",l_arrs8InputName);
    Cut_file(l_arrs8InputName);    
   }
  }
 }
}

运行结果:

biao@ubuntu:~/test/photo$ gcc CutFile.cpp 
biao@ubuntu:~/test/photo$ ls
a.out  CutFile.cpp  image  outfile
biao@ubuntu:~/test/photo$ ./a.out 
./image/1Y083642.jpg
./image/1Y083714.jpg
./image/1Y083747.jpg
./image/1Y083820.jpg
./image/1Y083853.jpg
./image/1Y083925.jpg
./image/1Y084157.jpg
./image/1Y084228.jpg
./image/1Y084301.jpg
./image/1Y084334.jpg
./image/1Y084406.jpg
./image/1Y084439.jpg
./image/1Y084711.jpg
./image/1Y084742.jpg
./image/1Y173524.jpg
./image/1Y173556.jpg
./image/1Y173629.jpg
./image/1Y173702.jpg
./image/1Y173933.jpg
./image/1Y174004.jpg
./image/1Y174244.jpg
./image/1Y174315.jpg
./image/1Y174348.jpg
./image/1Y174420.jpg
./image/1Y174454.jpg
./image/1Y174733.jpg
biao@ubuntu:~/test/photo$ tree
.
├── a.out
├── CutFile.cpp
├── image
│   ├── 1Y083642.jpg
│   ├── 1Y083714.jpg
│   ├── 1Y083747.jpg
│   ├── 1Y083820.jpg
│   ├── 1Y083853.jpg
│   ├── 1Y083925.jpg
│   ├── 1Y084157.jpg
│   ├── 1Y084228.jpg
│   ├── 1Y084301.jpg
│   ├── 1Y084334.jpg
│   ├── 1Y084406.jpg
│   ├── 1Y084439.jpg
│   ├── 1Y084711.jpg
│   ├── 1Y084742.jpg
│   ├── 1Y173524.jpg
│   ├── 1Y173556.jpg
│   ├── 1Y173629.jpg
│   ├── 1Y173702.jpg
│   ├── 1Y173933.jpg
│   ├── 1Y174004.jpg
│   ├── 1Y174244.jpg
│   ├── 1Y174315.jpg
│   ├── 1Y174348.jpg
│   ├── 1Y174420.jpg
│   ├── 1Y174454.jpg
│   └── 1Y174733.jpg
└── outfile
    ├── 000.jpg
    ├── 0010.jpg
    ├── 0011.jpg
    ├── 0012.jpg
    ├── 0013.jpg
    ├── 0014.jpg
    ├── 0015.jpg
    ├── 0016.jpg
    ├── 0017.jpg
    ├── 0018.jpg
    ├── 0019.jpg
    ├── 001.jpg
    ├── 0020.jpg
    ├── 0021.jpg
    ├── 0022.jpg
    ├── 0023.jpg
    ├── 0024.jpg
    ├── 0025.jpg
    ├── 002.jpg
    ├── 003.jpg
    ├── 004.jpg
    ├── 005.jpg
    ├── 006.jpg
    ├── 007.jpg
    ├── 008.jpg
    └── 009.jpg
 
2 directories, 54 files
biao@ubuntu:~/test/photo$ 

运行前需要创建两个目录,image用来存放需要处理的图片,outfile用来存放处理过后的文件。这种处理文件批处理方式很暴力,偶尔用用还是可以的。

5、IO控制小程序

嵌入式设备系统一般为了节省空间,一般都会对系统进行裁剪,所以很多有用的命令都会被删除。在嵌入式设备中要调试代码也是比较麻烦的,一般只能看串口打印。现在写了个小程序,专门用来查看和控制海思Hi3520DV300芯片的IO电平状态。

/*=============================================================================
#     FileName: Hi3520_IO_CTRL.cpp
#         Desc: Hi3520DV300 IO Write and  Read
#       Author: Caibiao Lee
#      Version: 
#   LastChange: 2018-11-30
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include "hstGpioAL.h"
 
int PrintfInputTips(char *ps8Name)
{
 printf("=========== error!!! ========\n\n");
 printf("usage Write: %s GPIO bit value \n", ps8Name);
 printf("usage Read : %s GPIO bit \n", ps8Name);
 printf("eg Write 1 to GPIO1_bit02  :     %s 1 2 1\n", ps8Name);
 printf("eg Read  GPIO1_bit02 Value :     %s 1 2 \n\n", ps8Name);
 
 printf("=============BT20==================\n")
 printf("USB HUB    GPIO_0_2  1_UP; 0_Down \n");
 printf("RESET_HD   GPIO_13_0 0_EN; 1_disEN\n");
 printf("Power_HD   GPIO_13_3 1_UP; 0_Down \n");
 return 0;
}
 
int main(int argc, char **argv)
{
 if((3!=argc)&&(4!=argc))
 {
  PrintfInputTips(argv[0]);
  return -1;
 }
 
 unsigned char l_u8GPIONum = 0;
 unsigned char l_u8GPIOBit = 0;
 unsigned char l_u8SetValue = 0;
 
 GPIO_GROUP_E  l_eGpioGroup;
 GPIO_BIT_E   l_eBit;
 GPIO_DATA_E   l_eData;
 
 l_u8GPIONum   = atoi(argv[1]);
 l_u8GPIOBit   = atoi(argv[2]);
 
 if(l_u8GPIONum<14)
 {
  l_eGpioGroup = (GPIO_GROUP_E)l_u8GPIONum;
 }else
 {
  printf("l_u8GPIONum error l_u8GPIONum = %d\n",l_u8GPIONum);
  return -1;
 };
 
 if(l_u8GPIOBit<8)
 {
  l_eBit = (GPIO_BIT_E)l_u8GPIOBit;
 }else
 {
  printf("l_u8GPIOBit error l_u8GPIOBit = %d\n",l_u8GPIOBit);
  return -1;
 }
 
 if(NULL!=argv[3])
 {
  l_u8SetValue = atoi(argv[3]);
  if(0==l_u8SetValue)
  {
   l_eData = (GPIO_DATA_E)l_u8SetValue;
  }else if(1==l_u8SetValue)
  {
   l_eData = (GPIO_DATA_E)l_u8SetValue;
  }else
  {
   printf("l_u8SetValue error l_u8SetValue = %d\n",l_u8SetValue);
  }
 }
 
 if(3==argc)                                                       
 {/**read**/                                                                                                                                                      
     printf("read GPIO%d Bit%d \n",l_u8GPIONum,l_u8GPIOBit);           
        /**set input**/                                               
        HstGpio_Set_Direction(l_eGpioGroup, l_eBit, GPIO_INPUT);                        
                                                                                          
     /**read **/                                                                               
     char l_s8bit_val = 0;                                                                     
     HstGpio_Get_Value(l_eGpioGroup, l_eBit, &l_s8bit_val);                                    
                                                                                               
     printf("read Data = %d \n",l_s8bit_val);                                                  
                                                                                                 
   }else if(4==argc)                                                                             
   {/**write**/                                                                                                                                                                            
       printf("Write GPIO %d; Bit %d; Value %d\n",l_u8GPIONum,l_u8GPIOBit,l_u8SetValue);         
                                                                                                 
       /***set IO output*/                                                                       
       HstGpio_Set_Direction(l_eGpioGroup, l_eBit, GPIO_OUPUT);                                  
                                                                                                 
       /**Write To IO**/ 
    HstGpio_Set_Value(l_eGpioGroup,l_eBit,l_eData);
   }else                                            
   {                                                                                             
                                                                                                 
   }
 
 return 0;
 
}

6、文件固定位置插入数据

在文件的固定位置插入固定的数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define BASIC_FILE_NAME  "./nandflash.bin"
#define UBOOT_FILE_NAME  "./u-boot.bin"
#define KERNEL_FILE_NAME "./kernel.bin"
#define ROOTFS_FILE_NAME "./rootfs.bin"
#define APP_FILE_NAME  "./app.bin"
 
 
#define UBOOT_POSITION  0x00
#define KERNEL_POSITION  0x100000
#define ROOTFS_POSITION  0x500000
#define APP_POSITION  0x2700000
 
 
 
int InsertData(FILE *pfBasic,FILE *psInsert,int s32Position)
{
 int l_S32Ret = 0;
 unsigned char l_arru8Temp[1024] = {0xff};
 
 fseek(pfBasic,s32Position,SEEK_SET);
 fseek(psInsert,0,SEEK_SET);
 while(1)
 {
  l_S32Ret = fread(l_arru8Temp,1,1024,psInsert);
  if(l_S32Ret > 0)
  {
   l_S32Ret = fwrite(l_arru8Temp,1,l_S32Ret,pfBasic);
   if(l_S32Ret<=0)
   {
    printf("line %d error l_S32Ret = %d \n",__LINE__,l_S32Ret);
    return -1;
   }
  }else
  {
   break;
  }
 }
 
 return 0;
}
 
 
 
int main(void)
{
 int l_s32Ret = 0;
 FILE *l_pfBasec = NULL;
 FILE *l_pfUboot = NULL;
 FILE *l_pfKernel = NULL;
 FILE *l_pfRootfs = NULL;
 FILE *l_pfApp = NULL;
 
 
 l_pfBasec = fopen(BASIC_FILE_NAME,"r+");
 if(NULL==l_pfBasec)
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 l_pfUboot = fopen(UBOOT_FILE_NAME,"r");
 if(NULL==l_pfUboot)
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 l_pfKernel = fopen(KERNEL_FILE_NAME,"r");
 if(NULL==l_pfKernel)
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 l_pfRootfs = fopen(ROOTFS_FILE_NAME,"r");
 if(NULL==l_pfRootfs)
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 l_pfApp = fopen(APP_FILE_NAME,"r");
 if(NULL==l_pfApp)
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 if(0> InsertData(l_pfBasec,l_pfUboot,UBOOT_POSITION))
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 if(0> InsertData(l_pfBasec,l_pfKernel,KERNEL_POSITION))
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 if(0> InsertData(l_pfBasec,l_pfRootfs,ROOTFS_POSITION))
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 if(0> InsertData(l_pfBasec,l_pfApp,APP_POSITION))
 {
  printf("line %d error \n",__LINE__);
  goto ERROR;
 }
 
 
ERROR:
 if(NULL!=l_pfBasec)
 {
  fclose(l_pfBasec);
  l_pfBasec = NULL;
 }
 
 if(NULL!=l_pfUboot)
 {
  fclose(l_pfUboot);
  l_pfUboot = NULL;
 }
 
 if(NULL!=l_pfKernel)
 {
  fclose(l_pfKernel);
  l_pfKernel = NULL;
 }
 
 
 if(NULL!=l_pfRootfs)
 {
  fclose(l_pfRootfs);
  l_pfRootfs = NULL;
 }
 
 if(NULL!=l_pfApp)
 {
  fclose(l_pfApp);
  l_pfApp = NULL;
 }
 
 return 0;
}

7、获取本地IP地址

在linux设备中获取本地IP地址可以使用下面的程序,支持最大主机有三个网口的设备,当然这个网卡数可以修改。

#include <stdio.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
 
int get_local_ip(char *ps8IpList)
{
    struct ifaddrs *ifAddrStruct;
    char l_s8IpAddr[INET_ADDRSTRLEN];
    void *tmpAddrPtr;
    int l_s32IPCount = 0;
    
    getifaddrs(&ifAddrStruct);
    while (ifAddrStruct != NULL) 
    {
        if (ifAddrStruct->ifa_addr->sa_family==AF_INET)
        {
            tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
            inet_ntop(AF_INET, tmpAddrPtr, l_s8IpAddr, INET_ADDRSTRLEN);
            if (strcmp(l_s8IpAddr, "127.0.0.1") != 0) 
            {
                if(l_s32IPCount == 0)
                {
                        memcpy(ps8IpList, l_s8IpAddr, INET_ADDRSTRLEN);
                } else 
                {
                        memcpy(ps8IpList+INET_ADDRSTRLEN, l_s8IpAddr, INET_ADDRSTRLEN);
                }
                l_s32IPCount++;
            }
        }
        ifAddrStruct=ifAddrStruct->ifa_next;
    }
 
    freeifaddrs(ifAddrStruct);
    return l_s32IPCount;
}
 
int main()
{
    char l_arrs8IpAddrList[3][INET_ADDRSTRLEN];
    int l_s32AddrCount;
    
    memset(l_arrs8IpAddrList, 0, sizeof(l_arrs8IpAddrList));
 
    l_s32AddrCount = get_local_ip(*l_arrs8IpAddrList);
 
    for(l_s32AddrCount;l_s32AddrCount>0;l_s32AddrCount--)
    {
        printf("Server Local IP%d: %s\n",l_s32AddrCount,l_arrs8IpAddrList[l_s32AddrCount-1]);
    }
 
 return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣练习——链表在线OJ

目录 提示&#xff1a; 一、移除链表元素 题目&#xff1a; 解答&#xff1a; 二、反转链表 题目&#xff1a; 解答&#xff1a; 三、找到链表的中间结点 题目&#xff1a; 解答&#xff1a; 四、合并两个有序链表&#xff08;经典&#xff09; 题目&#xff1a; 解…

c++-vector

文章目录 前言一、vector介绍二、vector使用1、构造函数2、vector 元素访问3、vector iterator 的使用4、vector 空间增长问题5、vector 增删查改6、理解vector<vector< int >>7、电话号码的字母组合练习题 三、模拟实现vector1、查看STL库源码中怎样实现的vector2…

(四)激光线扫描-光平面标定

在上一章节,已经实现了对激光线条的中心线提取,并且在最开始已经实现了对相机的标定,那么相机标定的作用是什么呢? 就是将图像二维点和空间三维点之间进行互相转换。 1. 什么是光平面 激光发射器投射出一条线,形成的一个扇形区域平面就是光平面,也叫光刀面,与物体相交…

linux下查找文件的相关命令

linux下查找文件的相关命令 运行环境&#xff1a;centos7 参考来源&#xff1a;man、鸟哥入门书籍 一、脚本文件查找&#xff1a;which/type 1. which man手册描述&#xff1a; 返回当前环境可以被执行的文件&#xff08;或链接&#xff09;的路径。搜索PATH变量匹配参数中…

vuejs开发环境搭建

Vuejs是一个前端页面应用开发框架&#xff0c;它基于标准 HTML、CSS 和JavaScript 构建&#xff0c;支持不同的JavaScript开发规范&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面&#xff0c;本文主要描述Vuejs开发环境的搭建。Vuej…

大规模语言模型--训练成本

目前&#xff0c;基于 Transformers 架构的大型语言模型 (LLM)&#xff0c;如 GPT、T5 和 BERT&#xff0c;已经在各种自然语言处理 (NLP) 任务中取得了 SOTA 结果。将预训练好的语言模型(LM) 在下游任务上进行微调已成为处理 NLP 任务的一种 范式。与使用开箱即用的预训练 LLM…

基于SSM的视频点播系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

C++语言GDAL批量裁剪多波段栅格图像:基于像元个数裁剪

本文介绍基于C 语言的GDAL模块&#xff0c;按照给定的像元行数与列数&#xff0c;批量裁剪大量多波段栅格遥感影像文件&#xff0c;并将所得到的裁剪后新的多波段遥感影像文件保存在指定路径中的方法。 在之前的文章中&#xff0c;我们多次介绍了在不同平台&#xff0c;或基于不…

TouchGFX之后端通信

在大多数应用中&#xff0c;UI需以某种方式连接到系统的其余部分&#xff0c;并发送和接收数据。 它可能会与硬件外设&#xff08;传感器数据、模数转换和串行通信等&#xff09;或其他软件模块进行交互通讯。 Model类​ 所有TouchGFX应用都有Model类&#xff0c;Model类除了存…

色彩一致性自动处理方法在遥感图像中的应用

前言 在获取卫星遥感影像时&#xff0c;由于受不均匀的光照、不同的大气条件和不同的传感器设备等因素的影响&#xff0c;遥感影像中会存在局部亮度和色彩分布不均匀的现象&#xff0c;下面是在BigMap地图下载器中收集的几幅谷歌卫星影像&#xff0c;像下面这种都是拼接好的影像…

从零开始的C++(四)

上篇链接&#xff1a;http://t.csdnimg.cn/3nyT9 1.拷贝构造函数&#xff1a; 上篇中介绍了析构函数&#xff0c;即在对象销毁时自动调用的函数&#xff0c;常用于含有malloc、fopen等成员变量的对象。然而&#xff0c;在将对象做函数实参进行值传递的时候&#xff0c;可能会…

Unity宣布自2024年起将根据游戏安装量收费,你对此有何看法?

文章目录 每日一句正能量前言Unity的来历Unity的应用对于收费的看法个人角度&#xff1a;公司角度&#xff1a; 后记 每日一句正能量 水与水之间有距离&#xff0c;但地心下直相牵&#xff0c;人与人之间有距离&#xff0c;但心里时刻挂念&#xff0c;发条短信道声晚安&#xf…

【强化学习】05 —— 基于无模型的强化学习(Prediction)

文章目录 简介蒙特卡洛算法时序差分方法Example1 MC和TD的对比偏差&#xff08;Bias&#xff09;/方差&#xff08;Variance&#xff09;的权衡Example2 Random WalkExample3 AB 反向传播(backup)Monte-Carlo BackupTemporal-Difference BackupDynamic Programming Backup Boot…

深入浅出,SpringBoot整合Quartz实现定时任务与Redis健康检测(一)

目录 前言 环境配置 Quartz 什么是Quartz&#xff1f; 应用场景 核心组件 Job JobDetail Trigger CronTrigger SimpleTrigger Scheduler 任务存储 RAM JDBC 导入依赖 定时任务 销量统计 Redis检测 使用 ​编辑 注意事项 前言 在悦享校园1.0中引入了Quart…

番外3:下载+安装VMware(前期准备)

step1: 查看自己笔记本电脑配置&#xff1b; step2: 下载并安装VMware&#xff08;下载地址www..kkx.net/soft/16841.html&#xff09;这里选择本地普通下载&#xff1b; step3: 安装VMware过程中需要填写密钥&#xff08;本人用的最后一个&#xff09;; #UU54R-FVD91-488PP-7N…

国庆day4

运算符重载代码 #include <iostream> using namespace std; class Num { private:int num1; //实部int num2; //虚部 public:Num(){}; //无参构造Num(int n1,int n2):num1(n1),num2(n2){}; //有参构造~Num(){}; //析构函数const Num operator(const Num &other)cons…

微服务技术栈-Ribbon负载均衡和Nacos注册中心

文章目录 前言一、Ribbon负载均衡1.LoadBalancerInterceptor&#xff08;负载均衡拦截器&#xff09;2.负载均衡策略IRule 二、Nacos注册中心1.Nacos简介2.搭建Nacos注册中心3.服务分级存储模型4.环境隔离5.Nacos与Eureka的区别 总结 前言 在上面那个文章中介绍了微服务架构的…

【C语言】函数的定义、传参与调用(一)

目录 导读&#xff1a; 1. 为什么要用函数 2. C语言中函数的分类 2.1 库函数 2.1.1 什么是库函数 2.1.2 C语言常用的库函数 2.2 自定义函数 2.2.1 什么是自定义函数 2.2.2 定义函数的方法 2.2.3 举例 3. 函数的参数 3.1 传参不同的对比 3.2 形式参数&#xff08;形…

以太网基础学习(一)——以太网概述

一、以太网概述 以太网(Ethernet)指的是由 Xerox公司创建并由Xerox、Intel和 DEC公司联合开发的基带局域网规范&#xff0c;通用的以太网标准于1980年9月30日出台&#xff0c;是当今现有局域网采用的最通用的通信协议标准&#xff08;是局域网的一种&#xff09;。 以太网是一种…

libevent源码学习笔记

libevent源码学习笔记 libevent安装libevent源码解析&#xff08;1&#xff09;事件对象&#xff08;2&#xff09;事件操作&#xff08;3&#xff09;事件循环&#xff08;4&#xff09;事件处理 常用指令问题记录问题一&#xff1a;长连接的管理问题二&#xff1a;连接关闭问…