2016-07-27 5 views
1

OSに実装されているprintf()関数にバグがあります。基本的に問題は、それがリストを通って増加することです。例えば、私が持って言うことができます:私のOS上で表示されますどのようなva_argがインクリメントしていないC++

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

は次のとおりです。

19 19 

何らかの理由で58はthourghつもりはありません。私は上記のように、それはありませんが、

#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 

#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の:私はここでstdio.C++である:(かなりの時間のためにこれをデバッグしているが、問題を見つけるカント何らかの理由で引数によってインクリメントいただければ幸いヘルプ:)

+0

あなたはva_start @RyanBemroseを意味しますか?もしそうなら、私はそれをしてまだ仕事をしなかった:( – amanuel2

答えて

3

パスargをごputchar関数に参照することにより代わりの値によって:。!

​​

putchar関数内でインクリメントされますが、printfの変数には何の影響もありません。putcharには参照ではなくコピーが渡されるためです。

+0

ああ、ありがとう:) – amanuel2

関連する問題