字符串值数组中缺少条目

时间:2019-05-16 13:14:35

标签: c arrays string memory

我正在尝试创建用于识别某些硬件通道的字符串的const char数组。然后,我想按索引检索这些条目以标记用户控制台上的输出。其中一些通道​​未分配,并使用字符串“ XX_UNASSIGNED_XX”标记,因此该值在数组中重复。

当我尝试在测试代码中顺序显示这些值时,我看到XX_UNASSIGNED_XX仅出现一次,随后被跳过。我在嵌入式硬件中打开了内存跟踪,可以肯定的是,内存仅列出了XX_UNASSIGNED_XX次,我认为这是一种优化。

是否有一种方法可以强制编译器改为按原样列出内存中的每个条目,重复项和全部?或者,是否有可能我不需要这样做,并且我尝试显示字符串的方式不正确或效率低下,可以改进吗?

我一直在研究如何显示字符串,因为它最终是一个指针数组,每个字符串的长度都不同,所以我最终导致记录每个字符串的长度,使用指针变量跟踪该数组,然后使用snprintf将字符串复制到临时字符串,然后显示该临时字符串。直接打印数组中值的任何尝试都会导致我似乎无法纠正的异常行为。

FYI Display_printf命令只是到UART终端的printf,语法如下:

Display_printf(UART_handle,col_index, row_index, display_text))
    #define ADC_COUNT (20)

    const char* adcNamesArray[ADC_COUNT] = {
        "KP_CUR_MON",
        "A_CUR_MON",
        "A_VOLT_MON",
        "NEG_15_VOLT_MON",
        "XX_UNASSIGNED_XX",
        "FOCUS_CUR_MON",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "K_CUR_MON",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "FOCUS_VOLT_MON",
        "FARADAY_MON",
        "MFC_MON",
        "XX_UNASSIGNED_XX",
        "POS_12_VOLT_MON",
        "POS_24_VOLT_MON",
        "POS_15_VOLT_MON",
        "POS_5_VOLT_MON"
    };

    char str[20];
    char* ptr = &adcNamesArray[0];
    char* printPtr;
    int nameLength;

    for(int adc_index = 0; adc_index < ADC_COUNT; adc_index++) {
        nameLength = 0;

        while(*ptr == '\0') {
            ptr += sizeof(char);
        }
        printPtr = ptr;

        while(*ptr != '\0') {
            ptr += sizeof(char);
            nameLength++;
        }
        nameLength++;

        char* str;
        str = (char *)malloc((sizeof(char)*nameLength+1));
        snprintf(str, nameLength, "%s", printPtr);

        Display_printf(display,0,0,"ADC %d: %s", adc_index, str);
    }

因此,我希望所有XX_UNASSIGNED_XX条目都按顺序显示,但是我得到的是:

ADC 0: KP_CUR_MON  
ADC 1: A_CUR_MON  
ADC 2: A_VOLT_MON  
ADC 3: NEG_15_VOLT_MON   
ADC 4: XX_UNASSIGNED_XX   
ADC 5: FOCUS_CUR_MON   
ADC 6: K_CUR_MON   
ADC 7: FOCUS_VOLT_MON   
ADC 8: FARADAY_MON   
ADC 9: MFC_MON   
ADC 10: POS_12_VOLT_MON   
ADC 11: POS_24_VOLT_MON   
ADC 12: POS_15_VOLT_MON   
ADC 13: POS_5_VOLT_MON   
ADC 14: ▒   
ADC 15: @   
ADC 16: ▒▒▒▒   
ADC 17: @▒   
ADC 18:   
ADC 19:  

通过查看内存转储可以看到这一点,这说明了为什么XX_UNASSIGNED_XX无法多次显示。

0x0001C0D8  .  .  .  .  .  .  .  0  K  P  _  C  U  R  _  M  
0x0001C0E8  O  N  .  .  A  _  C  U  R  _  M  O  N  .  .  .  
0x0001C0F8  A  _  V  O  L  T  _  M  O  N  .  .  N  E  G  _  
0x0001C108  1  5  _  V  O  L  T  _  M  O  N  .  X  X  _  U  
0x0001C118  N  A  S  S  I  G  N  E  D  _  X  X  .  .  .  .  
0x0001C128  F  O  C  U  S  _  C  U  R  _  M  O  N  .  .  .  
0x0001C138  K  _  C  U  R  _  M  O  N  .  .  .  F  O  C  U  
0x0001C148  S  _  V  O  L  T  _  M  O  N  .  .  F  A  R  A  
0x0001C158  D  A  Y  _  M  O  N  .  M  F  C  _  M  O  N  .  
0x0001C168  P  O  S  _  1  2  _  V  O  L  T  _  M  O  N  .  
0x0001C178  P  O  S  _  2  4  _  V  O  L  T  _  M  O  N  .  
0x0001C188  P  O  S  _  1  5  _  V  O  L  T  _  M  O  N  .  
0x0001C198  P  O  S  _  5  _  V  O  L  T  _  M  O  N  .  .  
0x0001C1A8  uartMSP432E4HWAttrs  
0x0001C1A8  .  .  .  @  .  .  .  .  .  .  .  .  .  .  .  .  
0x0001C1B8  @  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您假定文本在内存中是连续的,由一个或多个NUL字符分隔。这个假设是错误的。

这声明了一个指向文本的指针数组:

const char* adcNamesArray[ADC_COUNT] = {
...

只需使用该数组,一下子您的代码就会变得更加简单和正确。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ADC_COUNT (20)

int main(void)
{
  const char* adcNamesArray[ADC_COUNT] = {
         "KP_CUR_MON",
         "A_CUR_MON",
         "A_VOLT_MON",
         "NEG_15_VOLT_MON",
         "XX_UNASSIGNED_XX",
         "FOCUS_CUR_MON",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "K_CUR_MON",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "FOCUS_VOLT_MON",
         "FARADAY_MON",
         "MFC_MON",
         "XX_UNASSIGNED_XX",
         "POS_12_VOLT_MON",
         "POS_24_VOLT_MON",
         "POS_15_VOLT_MON",
         "POS_5_VOLT_MON"
  };

  for (int adc_index = 0; adc_index < ADC_COUNT; adc_index++)
  {
    char *str = malloc(strlen(adcNamesArray[adc_index]) + 1);
    strcpy(str, adcNamesArray[adc_index]);
    printf("ADC %d: %s\n", adc_index, str);
  }
}

如果您出于某种原因在平台上没有strcpystrlen,则可以自己实现,因为它们是一线的。

一些解释:

  • sizeof char根据定义为1,因此可以将其删除
  • (char*)不需要malloc强制转换,放置一个并没有错,但是这样做的好处为零。