Отговори на тема  [ 18 мнения ]  Отиди на страница 1, 2  Следваща
String и Pointer в CCS, проблеми... 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение String и Pointer в CCS, проблеми...
Проблема ми е следния:

Код:
struct DirEntry {
                 unsigned char DIR_Name[8];      //8 chars filename
                 unsigned char DIR_Ext[3];       //3 chars extension
                 unsigned char DIR_Attr;         //file attributes RSHA
                 unsigned char DIR_NTres;        //set to zero
                 unsigned char DIR_CrtTimeTenth; //creation time part in milliseconds
                 unsigned int  DIR_CrtTime;      //creation time
                 unsigned int  DIR_CrtDate;      //creation date
                 unsigned int  DIR_LastAccDate;  //last access date (no time for this !)
                 unsigned int  DIR_FstClusHI;  //first cluster high word
                 unsigned int  DIR_WrtTime;      //last write time
                 unsigned int  DIR_WrtDate;      //last write date
                 unsigned int  DIR_FstClusLO;  //first cluster low word
                 unsigned long DIR_FileSize;
                };   

void MakeNewFileEntry(char *name,char *ext,int16 clnum,int16 size)
{ struct DirEntry dir;
 
   strcpy(dir.DIR_Name,name);
   strcpy(dir.DIR_Ext,ext);
   printf("New File Created: %S %S",dir.DIR_Name,dir.DIR_Ext); 
   
}


При извикване на МакеNewFileEntry по следните начини:
Код:
MakeNewFileEntry("Errors","TXT",3,2);

Бих очаквал да ми се изпринтира "New File Created: ErrorsTXT", но компилатора казва: "Expecting variable such as LVALUE or...." и ми сочи към "Errors" стринга. Предполагам, че това не е правилния начин да си извикам процедурата, затова пробвах по втори начин:
Код:
char *fname,fext;
...
...
strcpy(fname,"Errors");
strcpy(fext,"TXT");
MakeNewFileEntry(fname,fext,3,2);

Това се компилира, обаче в резултат ми изписва само "New File Created:".
Къде бъркам? Защо не мога да извикам процедурата във вид MakeNewFileEntry("Errors","TXT",3,2) ?


Вто Фев 22, 2005 2:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
защото PIC няма указател към стринг и въобще към константа, защото той е с харвардска организация и "Errors" въобще го няма в RAM-a, та да има поинтер към него.


Вто Фев 22, 2005 3:43 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Добре де...това:
strcpy(fname,"Errors"), не качва ли текст във fname (във RAM-а)...как тогава въобще работи strcpy(), след като е написана по следния начин:
Код:
/*    Standard template: char *strcpy(char *s1, const char *s2)
copies the string s2 including the null character to s1*/

char *strcpy(char *s1, char *s2)
{
  char *s;

  for (s = s1; *s2 != 0; s++, s2++)
     *s = *s2;
  return(s1);
}
???


Вто Фев 22, 2005 3:48 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
Ako си го копнал от някоя библиотека на CCS - нямам думи!
Компилирай го и виж компилаторът какъв .ASM ти е сгенерирал. Сигурно ще се натъкнеш на инструкцията RETLF или нещо подобно.


Вто Фев 22, 2005 4:27 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Точно оттам съм го копнал (не можах да разбера това за думите :?: )... и като гледам на ASM работи с INDF-a...що не мога да схвана...по принцип трябва да работи, това си е C...егати :!:

EDIT:
Доколкото имам опит в CCS-a, знам че '*' означава "address of". T.e. ако дефинираш
Код:
#define A 0x05

и използваш А така:
Код:
*А = 0xEA;

...е същото като това:
Код:
#byte A = 0x05
...
A = 0xEA;


Вто Фев 22, 2005 4:51 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение Re: String и Pointer в CCS, проблеми...
Не съм сигурен, но мисля, че оплакването идва от факта, че функцията очаква variable, а ти им подаваш константа.

При втория начин fname е указател, който не е инициализиран - класически пример за мазане някъде по паметта (а може там да няма памет). А пък fext е само един символ, а ти пишеш в него 4 (плюс нулата). Правилно е да ти даде грешка при strcpy (fext,"TXT");

Мисля, че ще имаш и друг проблем - strcpy копира докато срещне 0, но копира и 0-та. Както ти е направена структурата, копирането с strcpy на име, което е 8 символа, ще доведе до копиране на 0-та в началото на разширението. Също така и копирането на разширение от 3 символа ще доведе до копиране на 0 в следващото поле.


Вто Фев 22, 2005 6:36 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Донякъде има логика, това за Variable-а го разбрах още като го писах...само че пак не схващам...В help-а на CCS пише следното за strcpy:
Код:
Syntax:
strcpy (dest, src)

Parameters:
dest is a pointer to a RAM array of characters.

src may be either a pointer to a RAM array of characters or it may be a constant string.

Function:
Copies a constant or RAM string to a RAM string.  Strings are terminated with a 0.

Availability:
All devices.

Requires
Nothing

Examples:
char string[10], string2[10];

...
strcpy (string, "Hi There");

strcpy(string2,string);



Значи, трябва ли да разбирам, че предварително трябва да обявявам дължината на стринга (което би било доста тъпо)...И защо във кода на strcpy е обявена променлива *s...значи то вероятно работи...но как? Тая вечер ще си поблъскам тиквата с още такива въпроси :wink:


Вто Фев 22, 2005 6:46 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
Predator_MF написа:
Донякъде има логика, това за Variable-а го разбрах още като го писах...само че пак не схващам...

По принцип константите и променливите (могат да) стоят в различни сегменти, типове памет, и ... Затова в C са дефинирани като различни. Не съм писал за PIC, но най-вероятно константните стрингове се слагат някъде след програмата във flash/eprom.

Predator_MF написа:
Значи, трябва ли да разбирам, че предварително трябва да обявявам дължината на стринга (което би било доста тъпо)...И защо във кода на strcpy е обявена променлива *s...значи то вероятно работи...но как? Тая вечер ще си поблъскам тиквата с още такива въпроси :wink:

Вариантите за работа със стрингове са два. Първия да са с предварително зададен размер, другия е да са динамично заделени с malloc. Това е възможно ако конкретната системна библиотека има поддръжка на функциите malloc/realloc/free. Ако няма, може да си ги направиш в част от RAM паметта, но ... може да се окаже, че е по-лесно да се работи с предварително зададени размери.


Вто Фев 22, 2005 7:03 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
Predator_MF написа:
...И защо във кода на strcpy е обявена променлива *s...значи то вероятно работи...но как?

А на тази променлива не се ли присвоява някаква стойност преди да се използва?
Просто char *s е указател, т.е. адреса на масив от символи, а не самия масив от символи.


Вто Фев 22, 2005 7:06 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Хм, тогава това как работи?
Код:
/*    Standard template: char *strcpy(char *s1, const char *s2)
copies the string s2 including the null character to s1*/

char *strcpy(char *s1, char *s2)
{
  char *s;

  for (s = s1; *s2 != 0; s++, s2++)
     *s = *s2;
  return(s1);
}


Никъде не е дефинирано колко е дълъг "s"...


Вто Фев 22, 2005 7:12 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
Predator_MF написа:
Хм, тогава това как работи?
...
Никъде не е дефинирано колко е дълъг "s"...

Все пак може да погледнеш някоя книга за програмиране на C и по-конкретно за работа със стрингове и указатели. В C стринговете са поредица символи, завършваща с 0. Конкретно в тази функция се копира в s1 докато се срещне 0 в s2 (но трябва да копира и нулата, за да се получи отново валиден стринг по правилата на C).
Задължение на викащата функция е да подаде правилни входни параметри - указател s1, който сочи към достатъчно заделена памет, и указател s2, който сочи към стринг, написан по правилата на C - т.е. поредица символи, завършваща с 0.
Ако няма достатъчно място в масива, сочен от s1 (т.е. по-малко от колкото е дължината на s2), то се получава мазане в паметта след масива.

А тази функция според мен има проблем - не копира 0-та на края, защото цикъла се изпълнява докато *s2 != 0 и когато стане 0 тя не се записва в s. Искам да кажа, че ако имаш стринга "0123", то той заема 5 байта в паметта, а фунцията ще копира само 4. Последния, който е 0 няма да се копира и ще получиш стринг, който не е правилно терминиран.
И ако пуснеш нещо като:

char s1 [10], s2 [10];

memset (s1, 'a', 9);
s1 [9] = 0;
s2 [9] = 0;
strcpy (s1, "12345");
strcpy (s2, s1);
printf ("%s\n", s2);

ще видиш резултат:
12345aaaa
вместо
12345


Вто Фев 22, 2005 7:33 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
danov написа:
А тази функция според мен има проблем - не копира 0-та на края, защото цикъла се изпълнява докато *s2 != 0 и когато стане 0 тя не се записва в s. Искам да кажа, че ако имаш стринга "0123", то той заема 5 байта в паметта, а фунцията ще копира само 4. Последния, който е 0 няма да се копира и ще получиш стринг, който не е правилно терминиран.


CCS HELP написа:
...copies the string s2 including the null character to s1*/
...тука вече почвам да се бъркам здраво...довечера ще погледна малко в една книга, сигурен съм че ще измисля нещо...Благодаря за инфото :D


Вто Фев 22, 2005 7:48 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
За най-чисто ти предлагам да го изпробваш. Ще ми е интересно какъв е резултата.


Вто Фев 22, 2005 8:06 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Така, направих няколко опита...оказва се следното:

Код:
void printshit(char *s)
             { putc(s);}
....
printshit("Predator_MF");


Тоя код ми принтира "Predator_MF"...т.е. функцията ми се извиква Length(s) пъти с параметър s++...В случая нямаше значение дали ще дефинирам дължината на s (char s[10] примерно...). Странно, това не го знаех...Следващия ми опит беше да пробвам как работи strcpy(dest,src). Пробвах с това:
Код:
strcpy(s,"Predator_MF");
          printf(s);

Тука резултат няма, нищо не се принтира!!! Ако вместо printf(s) напиша:
Код:
for (i=0;i<10;putc(s[i]);

Резултата е print на "Predator_MF"...Проблема значи функцията strcpy си работи, проблема идва в принтирането...не знам точно защо :?: . Все пак решението не ми е известно още...няма значение, ще гледам да избягвам стриговете, поне тези в CCS за PIC...то така или иначе RAM-a им си е достатъчно малък че да го тъпча с такива неща...в случая "Да живее АСЕМБЛЕР!!!" :D


Чет Фев 24, 2005 3:47 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
@Предатор, това за Асемблера е вярно, ама отчасти. Ако сега започваш и не възнамеряваш да програмираш непрекъснато, то асемблерът е за предпочитане - лесно се учи и лесно се ползва. Сравнително лесно се дебъгва и трасира.
Ако обаче си решил с това да си вадиш хляба- то решението е C. Просто времето за "научаване" на езика се връща многократно при по-нататъшната работа. Програмира се по-бързо, и най-важното : имаш лесна миграция от един контролер на друг. (поне теоретично е така :wink: ). Естествено, нормално е езикът и компилаторът от време на време да ти вгорчават живота с някоя полова изненада, ама приеми го философски :D .


Чет Фев 24, 2005 9:18 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 18 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни