va_arg没有递增C ++

时间:2016-07-27 01:57:50

标签: c++ osdev variadic-functions

我的printf()函数实现了操作系统的错误。基本上问题是,它通过列表增加剂量。例如,假设我有:

printf("%d %d",19,58);

我的操作系统会显示:

19  19
58由于某种原因,没有进入thourgh。我已经调试了很长一段时间了,但是找不到问题:(。这是stdio.c ++:

#include "stdio.h"


static size_t terminal_row = 0;
static size_t terminal_column = 0;
static  uint16_t* VideoMemory =((uint16_t*)0xb8000);
static bool continue_ex = false;


SerialPort sp_std_io;


void printf(char *str, ...)
{
    va_list arg;
    va_start(arg, str);

    for(int32_t i=0;str[i]!='\0'; ++i)
        {
            putchar(str[i],str[i+1],arg);
        }

    va_end(arg);
}

void strcat(char *destination, const char *source)
{
    int x = 0;
    while (destination[x] != '\0')
    {
        x++;
    }
    for (int i=0; source[i] != '\0'; i++)
    {
        destination[x++] = source[i];
    }
    destination[x] = '\0';
}

void put_char_helper_neg(char chr)
{
    const size_t index =  (terminal_row * VGA_WIDTH +  terminal_column);
    terminal_column++;
    VideoMemory[index]= (VideoMemory[index] & 0xFF00)|chr;
}

void putstring_t(char str)
{
           size_t index =  (terminal_row * VGA_WIDTH +  terminal_column);
           terminal_column++;
           VideoMemory[index]= (VideoMemory[index] & 0xFF00)|str;
}


void putchar(char str,char next_str, va_list arg)
{
    if(!continue_ex)
    {
      uint32_t ch_per;
      char* str_use,str_use_space;
      const char per = '%';
         if(str == '\b')
            {
              terminal_column--;
            }
            const size_t index =  (terminal_row * VGA_WIDTH +  terminal_column);
            char space = ' ';
            switch(str)
            {
                case '\n':
                  terminal_row++;
                  terminal_column = 0;
                  break;
                case '\b':
                    VideoMemory[index]= (VideoMemory[index] & 0xFF00)|space;
                  break;
                case '%':
                    switch(next_str)
                    {
                    case 'd':
                        ch_per = va_arg(arg,int);
                        if(ch_per<0)
                        {
                            ch_per = -ch_per;
                            put_char_helper_neg('-');
                        }
                        str_use = itoa(ch_per);
                        terminal_column++;

                       for(int32_t i=0;str_use[i]!='\0'; ++i)
                       {
                          putstring_t(str_use[i]);
                       }

//                      sp_std_io.write_number_serial(ch_per);
//                      sp_std_io.write_string_serial(str_use);
                        continue_ex = true;
                        break;
                    default:
                        terminal_column++;
                        VideoMemory[index]= (VideoMemory[index] & 0xFF00)|per;
                    }
                    break;
                default:
                  terminal_column++;
                  VideoMemory[index]= (VideoMemory[index] & 0xFF00)|str;
                  break;
            }
    }
    else
    {
        continue_ex = false;
    }

}




int32_t strlen(int8_t* str)
{
    int32_t l=0;
    while(str[l]!='\0')l++;
    return l;
}


char *itoa(int val)

{
    uint8_t *ptr;
    static uint8_t buffer[16];
    ptr = buffer + sizeof(buffer);
    *--ptr = '\0';

    if (val == 0)
    {
        *--ptr = '0';
    }
    else while (val != 0)
    {
        *--ptr = (val % 10) + '0';
        val = val / 10;
    }
    return((char*)ptr);
}

和stdio.h:

#ifndef _STD_LIB_H_
#pragma once
#define _STD_LIB_H_ 1

#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include "math.h"
#include "serial.h"

static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;




//static int num_count_viedo_memory = 0;

void printf(char *str,...);
void putchar(char str,char next_str,va_list arg);
int32_t strlen(int8_t *str);
void strcat(char * Dest, char const * Src);
//int8_t* str_cat(int8_t *dest, const int8_t *src);
void reverse(char str[], int32_t length);
char* itoa(int val);
#endif

就像我上面描述的那样,由于某些原因,它并没有通过args递增。帮助将不胜感激! :)

1 个答案:

答案 0 :(得分:3)

通过引用而不是按值将arg传递到putchar函数中:

void putchar(char str,char next_str, va_list& arg)

正在发生的事情是它在putchar函数内增加,但随后函数返回,它对printf中的变量没有影响,因为putchar传递了一个副本而不是对它的引用。