常量数组的全局变量的替代方法?

时间:2017-12-12 17:54:47

标签: c global-variables const

我有一个在我的学校重新创建printf的项目。

我不想在我的代码中一直检查字符的格式说明符,因为我发现它很乱,很难看。

至于现在,我已经通过创建一些全局常量数组并使用它们进行检查找到了一种方法。但我不喜欢在我的代码中包含这么多全局变量的想法。

其中一个案例是全局变量是否可以?或者我应该使用其他方法来获得我想要的东西吗?

以下是我的开始:

全局const数组

const char  g_sp_integer[] = {
    'd',    //signed decimal int
    'i',    //signed decimal int
    'o',    //unsigned octal
    'u',    //unsigned decimal int
    'x',    //unsigned hex int
    'X',    //unsigned hex int (uppercase)
    '\0'
};

我的标题

#ifndef  FT_PRINTF_H
# define  FT_PRINTF_H

# include <stdarg.h>
# include <stdint.h>
# include <stdlib.h>

# include "libft.h"

# define SUCCESS (int32_t)0
# define FAILURE (int32_t)-1

/*
** Those extern definitions are used to check the specifier flags
*/

extern const char   *g_sp_integer;

int ft_printf(const char *format, ...);

#endif

我的printf函数

#include "ft_printf.h"

static int32_t  is_sp_integer(char c)
{
    uint32_t    i;

    while (g_sp_integer[i] != '\0')
    {
        if (g_sp_integer[i] == c)
            return (i);
        ++i;
    }
    return (FAILURE);
}

int ft_printf(const char *format, ...)
{
    va_list ap;
    char    *tmp;
    int32_t sp_type;

    tmp = format;
    va_start(ap, format);
    while (tmp != '\0')
    {
        if (tmp != '%')
        {
            ft_putchar(tmp);
            continue;
        }
        if ((sp_type = is_sp_integer(++tmp)) != FAILURE)
            ;   //parse_flag(sp_type);
        //continue checking the type of the specifier
    }
    va_end(ap);
    return (SUCCESS);
}

我想避免的事情:

这些只是简单的原型,但我想知道是否有一种正确的方法让我的功能干净利落。在我看来,这意味着我希望尽可能避免像这样进行检查:

if (c == 'd' || c == 'i')
    //manage the integer flag
else if (c == 'o')
    //manage the octal flag, etc.

如果不可能,最好的方式是我想避免的,请告诉我!

感谢大家的耐心,因为找到好的做法有时会很难!

编辑:

我使用的解决方案:

虽然第一个解决方案对我在这种情况下应该做的事情(在该文件中使用静态变量)有全局答案,但我已经结束了第二个答案中的建议,因为它符合我的需要,并避免使用静态或全局变量。

这是我的功能代码:

static int32_t is_sp_integer(char c) {
  const char    *sp_integer;
  const char    *sp_ptr;

  sp_integer = "dDioOuUxX";
  sp_ptr = sp_integer;
  while (*sp_ptr != '\0')
  {
    if (*sp_ptr == c)
      return (sp_ptr - sp_integer);
    ++sp_ptr;
  }
  return (FAILURE);
}

感谢大家!

2 个答案:

答案 0 :(得分:1)

g_sp_integer仅在is_sp_integer函数中使用,因此请在那里定义:

static int32_t  is_sp_integer(char c)
{
    const char  g_sp_integer[] = {
        'd',    //signed decimal int
        'i',    //signed decimal int
        'o',    //unsigned octal
        'u',    //unsigned decimal int
        'x',    //unsigned hex int
        'X',    //unsigned hex int (uppercase)
        '\0'
    };

    uint32_t    i;

    while (g_sp_integer[i] != '\0')
    {
        if (g_sp_integer[i] == c)
            return (i);
        ++i;
    }
    return (FAILURE);
}

答案 1 :(得分:0)

这是一个利用指针的不同实现。我认为它比使用数组更有效率。

const char  *g_sp_integer= "diouxX";
static int32_t  is_sp_integer(char c)
{
    const char *p = g_sp_integer;
    while (*p) {
        if (*p == c)
            return (p - g_sp_integer);
        p++;
    }
    return (FAILURE);
}