Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Проблеми с функцията long int atol(char *str)
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=4146
Страница 1 от 2

Автор:  Ugeen [ Чет Май 03, 2007 2:44 pm ]
Заглавие:  Проблеми с функцията long int atol(char *str)

Колоеги,опитвам се да преобразувам един стринг в число от типа long int и не става.Пиша на CodevisionAVR.Ето кода:
#include <mega8.h>
#include <string.h>
#include <stdio.h> // sprintf
#include <math.h>
#include <delay.h>
#include<stdlib.h>
#include<ctype.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
char Proba[]= {"123456"};
unsigned long int Counter;
char lcd_buffer[25];
//
void main(void)
(
PORTB=0x00;
DDRB=0xFF;
lcd_init(16);
while(1)
{
Counter=atol(Proba);
sprintf(lcd_buffer,"Counter=%u",Counter);
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer);
}
}

На дисплея извежда Counter=57920,нищо общо с истината.Компилатора е настроен функцията sprintf да работи с long,widht
Къде според вас е проблема?

Автор:  HCL [ Чет Май 03, 2007 3:21 pm ]
Заглавие: 

Опитай с
Код:
sprintf(lcd_buffer,"Counter=%ld",Counter);


%u e unsigned decimal integer, a atol врьща long int.

Автор:  Ugeen [ Чет Май 03, 2007 3:25 pm ]
Заглавие: 

Благодаря ти много ,така най-накрая проработи

Автор:  ps66 [ Чет Май 03, 2007 3:25 pm ]
Заглавие: 

нещо за размисъл: (123456 % 65536) == 57920 :D

Автор:  HCL [ Чет Май 03, 2007 3:27 pm ]
Заглавие: 

Като се замисля май ще е по-добре с
Код:
Counter=(unsigned long)atol(Proba);
sprintf(lcd_buffer,"Counter=%lu",Counter);

Автор:  HCL [ Чет Май 03, 2007 3:42 pm ]
Заглавие: 

ps66 написа:
нещо за размисъл: (123456 % 65536) == 57920 :D


8O Вярно, а 65536 == 0x1000. Как го интерпретира компилаторьт за да извьрши подобна сметка само той си знае. ps66 как се сети?

Автор:  ps66 [ Чет Май 03, 2007 4:06 pm ]
Заглавие: 

HCL написа:
ps66 написа:
нещо за размисъл: (123456 % 65536) == 57920 :D


8O Вярно, а 65536 == 0x1000. Как го интерпретира компилаторьт за да извьрши подобна сметка само той си знае. ps66 как се сети?


очевидно е че проблема е свъзан с преобразуване на типове!
в такива случаи (проблеми :)) винаги е най-добре да се указва типа:

sprintf(lcd_buffer,"Counter=%ld", (long int)Counter);

разбира се %ld трябва да е (long int) ...

това което начинаещите не разбират при sprintf (и всички с форматиращ стринг) и арг. "...") е че компилатора си няма и на идея какво има в форматиращия стринг (може да е променен и при изпълнение!)- така че преди да извика sprintf - тъпче в стека аргументите според типа им ... а дали съотвестват на форматиращия стринг (ред и тип) - само "автора" знае :)


много от начинаещите обвиняват компилатора за това че sprintf не работи - а причината не е в него :)

Автор:  Цецо [ Чет Май 03, 2007 5:52 pm ]
Заглавие: 

Ми то това му е готиното на С-то. В повечето случаи компилатора разчита, че задклавиатурното устройство е наясно с типовете. Докато в по "висшите" езици тия проверки са вменени на компилатора. :)

Автор:  HCL [ Чет Май 03, 2007 6:19 pm ]
Заглавие: 

Като се отвори дума, ще познаете ли на кой език е написан този код :)

Код:
PRO sl
   Common Exchange, W_1, alpha_2, alpha_3

   Forward_Function sl_second
   Forward_Function sl_alpha

   z0 = 50.0
   perm = 2.20
   tang = 0.001
   leit = 5.813E7
   wand = 0.0032
   freq = 10E9
   wan2 = 0.00001

   qx = 0
   READ, qx, PROMPT='press [1] for default values or [2] for new:  '

   if qx EQ 2 then begin
   READ, z0, PROMPT='Wellenwiderstand Z0: '
   READ, perm, PROMPT='Relative Substratpermitivität: '
   READ, tang, PROMPT='Verlust-Winkel des Substrats: '
   READ, leit, PROMPT='Leitfähigkeit des Leiters: '
   READ, wand, PROMPT='Wandstärke des Substrats: '
   READ, freq, PROMPT='Betriebsfrequenz: '
   READ, wan2, PROMPT='Wandstärkes des Leiters: '
   endif

   last = 4.E-7*!Pi
   buf = sqrt(perm) * z0

   W_b = sl_second(perm, z0, wand, buf)
   PRINT, 'W/b = ' , W_b
   PRINT, 'W = ' , W_1

   alpha_1 = sl_alpha(z0, perm, tang, leit, wand, freq, wan2, last, buf)
   PRINT, 'alpha (Np/m) = ', alpha_1
   PRINT, 'alpha (dB/m) = ', alpha_2
   PRINT, 'alpha (dB/lambda) = ', alpha_3

END


FUNCTION sl_alpha, z0, perm, tang, leit, wand, freq, wan2, last, buf
   Common Exchange

   R = sqrt((2.*!Pi*freq*last) / (2.*leit))
   A = 1. + (2*W_1/(wand - wan2)) + ((wand + wan2)/(!Pi*wand - !Pi*wan2))*alog((2.*wand - wan2)/wan2)
   B = 1. + (wand/(0.5*W_1 + 0.7*wan2))*(0.5 + (0.414*wan2/W_1) + (alog(4.*!Pi*W_1/wan2)/(2.*!Pi)))

   alpha_d = !Pi*freq*sqrt(perm)*tang/3.E8

   if buf GT 120 then begin
   alpha_c = (0.16*R*B)/(z0*wand)
   endif else begin
   alpha_c = (0.0027*R*perm*z0*A)/(30.*!Pi*(wand - wan2))
   endelse

   alpha = alpha_d + alpha_c
   alpha_2 = alpha * 8.686
   alpha_3 = (3.E8/(10E9*sqrt(perm))) * alpha_2

   RETURN, alpha
END


FUNCTION sl_second, perm, z0, wand, buf
   Common Exchange

   x = (30.*!Pi/buf) - 0.441

   if buf GT 120 then begin
   Wb = 0.85 - sqrt(0.6 - x)
   endif else begin
   Wb = x
   endelse

   W_1 = wand * x

   RETURN, Wb
END

Автор:  Gogo [ Чет Май 03, 2007 8:03 pm ]
Заглавие: 

Горното не знам на какъв език е писано, ама за това:
ps66 написа:
нещо за размисъл: (123456 % 65536) == 57920 :D
Какво трябва да се размишлява над него!? То си е вярно.

Автор:  Cekins [ Пет Май 04, 2007 12:32 pm ]
Заглавие: 

На Fortran ми мяза ;)

Автор:  ps66 [ Пет Май 04, 2007 12:57 pm ]
Заглавие: 

Gogo написа:
Горното не знам на какъв език е писано, ама за това:
ps66 написа:
нещо за размисъл: (123456 % 65536) == 57920 :D
Какво трябва да се размишлява над него!? То си е вярно.


ако питаш сериозно: би трябвало да те наведе на мисълта че се печатат (само) младшите 2 байта от 123456, и ... да си зададеш въпроса: "защо?" :idea:

а онова в Уффтопика: прилича на последен модел фортран 77 :D

Автор:  HCL [ Пет Май 04, 2007 2:36 pm ]
Заглавие: 

Да, там са му корените, по-специално става вьпрос за IDL. Както се вижда от пьрвите няколко реда езикьт е с динамично присвояване на типовете. Което е супер удобно за настолни приложения и всякакви а ла Матлаб изпьлнения, обаче забелязвате ли точките след всяка константа. Там са защото без тях стават фалове от време на време. Така че си е много добре, че при С-то програмистьт е дльжен да внимава от кой вид са му променливите. Малко е кофти в началото, но с времето се свиква, надявам се :)

Автор:  Cekins [ Пет Май 04, 2007 3:07 pm ]
Заглавие: 

Точно по точките го познах :). Асистента дето ни водеше упражненията за тия точки писа двойки на преписвачите :)

Автор:  Gogo [ Пет Май 04, 2007 5:06 pm ]
Заглавие: 

ps66 написа:
Gogo написа:
Горното не знам на какъв език е писано, ама за това:
ps66 написа:
нещо за размисъл: (123456 % 65536) == 57920 :D
Какво трябва да се размишлява над него!? То си е вярно.


ако питаш сериозно: би трябвало да те наведе на мисълта че се печатат (само) младшите 2 байта от 123456, и ... да си зададеш въпроса: "защо?" :idea:
Да, сериозно питам и сега вече, с последното си обяснение ме хвърли в размисъл. Може ли да го обясниш като за новобранец! Ако може с примерче...

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/