HI-Tech C Compiler 9.70 problém so strcmp()

Zdravím.
Poprosím niekoho o radu so správnym použitím funkcie strcmp.
Pripájam testovací kód,no ani v ňom mi to nefunguje.
Samotná funkcia sa vykoná,ale program if aj else odignoruje a pokračuje od začiatku slučky.Vo watch vidím akú hodnotu funkcia vracia,akurát to ďalej nefunguje.

[code]
#include <stdio.h>
#include <string.h>

int bufer;
char p1 =“125”;
char p2 =“124”;

void main (void)
{
while (1)
{
if (strcmp(p1,p2)==0)
{
bufer=10;
}

			else
			{
   				bufer=5;
			}
	}	

}[/code]
Vopred vďaka,Relatko.

Neporovnáváš stringy, ale čísla char (a na ty funkce strcmp nefunguje, porovnává teď vlastně neexistující řetězce někde v paměti, na adresách 124 a 125). Stringy by byly:

char p1] ="125"; char p2] ="124"
Navíc kompilátor podmínku zřejmě vyoptimalizuje (záleží na překladači), protože u konstant ví předem výsledek a tak nefunkční kód vyhodí (nastaví obsah výsledku předem).

Zdravím.
Zmenil som to ako si mi poradil,ale žiaľ ani tak to nefunguje.
Všimol som si ešte jednu divnú vec,vo watch sa mi nedá zobraziť premenná bufer,takže nemôžem posúdiť či sa vplyvom otimalizácie programu niečo udialo.Čo vidím je návratová hodnota so strcmp a tá je O.K.
Relatko.

Zřejmě překladač proměnnou bufer úplně vyhodil, když viděl že se k ničemu nepoužívá. Mohlo by pomoct přesunout obsah while(1) v main() do samostatné funkce (která se bude volat z toho while), tím by se mohl dát ošálit, aby si myslel že bufer je potřeba někde vně funkce.

Nemohu bohužel otestovat, tento překladač nepoužívám, takže jen dohady.

Zdravím.
Premennú “bufer” už vo watch vidím,mal si pravdu bolo ju treba len presunúť.

Pripájam program,kde sa pokúšam do eeprom zapisovať a následne s nej čítať reťazce.


#include <string.h>
#include <stdio.h>
#include <pic.h>
#include	"delay.h"





char  r1[8]="retazec1";	//klasický reazec
char  r2[8]="retazec2";
char *p1;				//smerník na reazec
char *p2;
int  	bufer;			//pomocná premenná


void write_string(char  address, char  *string) 
{
      for(int i=0;i<8;i++)
	{   
      eeprom_write(address++,string*);   
   }
}

char read_string(char *address) 
{
      char i =0;
    char string[8];
    for (i=0; i<8; i++)
    {
       string*=eeprom_read(address++);   
    }
return string;
} 

void dekrement (char *p,char a)
			{
				*p =*p-a;
			}


void	main (void)
{



	while(1)
			{
				write_string(0,r1);//zápis reazca r1 do eeprom
				write_string(8,r2);//zápis reazca r2 do eeprom
				p1=read_string(0);//preèítanie hodnoty z eeprom do pointa p1
				p2=read_string(8);//preèítanie hodnoty z eeprom do pointa p2
				write_string(16,p1);//zápis pointa p1 do eeprom
				write_string(24,p1);//zápis pointa p2 do eeprom	
				DelayMs(20);			
				dekrement(&bufer,10);//musí byť; aby vo Watch zobrazilo premennú "bufer"
				bufer=strcmp(p1,p2);//porovnanie reazcov na ktoré ukazujú pointre p1 a p2
				bufer=strcmp(r1,r2);//porovnanie reazcov r1 a r2
				
			}
}

Na zápis slúži write_string(0,0)
na vyčítanie read_string(0)

Všetko funguje ako má ,no môj problém je v tom že pokiaľ porovnávam dva ( z eeprom) vyčítané smerníky strcmp(p1,p2)
tak aj napriek tomu že reťazce na ktoré ukazujú nie sú rovnaké my funkcia vráti nulu : (

Ale pri porovnaní “klasických” reťazcov strcmp(r1,r2) sa pri ich nerovnosti vráti číslo (+/-) zodpovedajúce rozdielu ,teda strcmp funguje

Čím to môže byť ? :frowning:**

Nemůžeš z funkce read_string vracet pointer na string. Je to lokální proměnná funkce a přestane existovat po návratu z funkce. Běžně překladače takový buffer vytvoří v zásobníku, u PIC se to myslím dělá na vrcholu haldy v RAM. V každém případě po ukončení funkce už ten buffer neexistuje. Přesněji, ten buffer se vytvoří v paměti vždy na stejném místě, porovnáváš pak 2 stejné pointery někde v paměti a proto je jejich obsah stejný.

Musíš si deklarovat 2 buffery string pro načtení textů jako globální proměnné a funkci read_string předávat na ně ukazatel, aby věděla kam to má načíst.

char string1[8];
char string2[8];
....
char read_string(char* address, char* string)
....
read_string(0, string1);
read_string(8, string2);

Nevím jak u verze 9.70, ve verzi 9.83 je knihovna pro práci s EEPROM(#include <eeprom_routines.h>).

Pokud definuješ proměnnou jen jako char x, x = (-128… +127), pokud potom zadáš x > 127, kompilátor buď ohlásí chybu, nebo to nějak “přežvejká”, ale můžou ti pak v programu vycházet blbosti. Pokud nutně nepotřebuješ pracovat se zápornými hodnoty definuj jako unsigned char x(x = 0…255).

Zřejmě ti nefunguje funkce char read_ string(char *address), proč máš takto definovanou promennou address?

Zdravím.
Ďakujem za pomoc,už to pracuje ako má.[code]
#include <string.h>
#include <stdio.h>
#include <pic.h>
#include <htc.h>
#include “delay.h”

unsigned char r1[9]=“12345678”; //klasický reťazec
unsigned char r2[9]=“abcdefgh”;
unsigned char r3[9];
unsigned char r4[9];
int bufer; //pomocná premenná

void write_string( unsigned char address,unsigned char string)
{
for(int i=0;i<8;i++)
{
eeprom_write(address++,string
);
}
}

unsigned char read_string(unsigned char *address,unsigned char string)
{
unsigned char i =0;
for (i=0; i<8; i++)
{
string
=eeprom_read(address++);
}
return string;
}

void dekrement (unsigned char *p,unsigned char a)
{
*p =*p-a;
}

void main (void)
{

while(1)
		{
			write_string(0,r1);//zápis reťazca r1 do eeprom
			write_string(8,r2);//zápis reťazca r2 do eeprom
			DelayMs(5);
			read_string(0,r3);//prečítanie hodnoty z eeprom do reťazca r3
			read_string(8,r4);//prečítanie hodnoty z eeprom do reťazca r4
			
			dekrement(&bufer,10);//musí byť aby vo Watch zobrazilo premennú "bufer"
			bufer=strcmp(r3,r4);//porovnanie reťazcov 
			
		}

}
[/code]
S pozdravom relatko.**

Inak mal si robit s najnovsim preklafacom… Viem ze pri prechode so starsej verzie na novsiu tam par veci pomenili, a nakoniec aj tak prejdes na novsiu.