webForumDet fria alternativet

Glosförhörarprogram

15 svar · 779 visningar · startad av taper lawyer

taper lawyerMedlem sedan jan. 200481 inlägg
#1

Morsning!

Jag försöker skapa ett program (i C) som kan förhöra mig på glosor. Detta går dock inte helt utan problem; när jag kör programmet kraschar det.

Glosorna förvaras i en textfil på detta vis:

ord1|ord2
annat_ord1|annat_ord2
annat_annat_ord1|annat_annat_ord2

Och så här ser min kod ut än så länge.

Tack på förhand!

pimmeMedlem sedan sep. 2001553 inlägg
#2

Så, problemet ligger i att du inte allokerar minne för tecknena, dvs du borde köra nåt sånt här: words*[0] = (char*)malloc(strlen(buf));
Sen när du kopierar in strängen buf till words*[0] så verkar du blanda ihop vilket index som anger vad. För att kopiera en sträng till en annan så bör du istället använda strcpy().**

taper lawyerMedlem sedan jan. 200481 inlägg
#3

Tack för hjälpen, men jag förstod nog inte riktigt det sista. Jag försöker få in ordet till vänster om |-tecknet i words[x][0], och det till höger i words[x][1]. Hur skall jag lösa det med strcpy()?

PeWMedlem sedan juni 20006 839 inlägg
#4

Tycker att du krånglar till det. Det skulle ju räcka med att läsa in varje rad och sen dela upp raden i två ord som läggs i varsin sträng. Sen kan du ju välja vad du vill göra med de orden beroende på hur du vill att glosförhörarprogrammet ska fungera. Typ:

#include <string.h>
#include <stdio.h>

static int wheretosplit(char *s,char ch) 
{
   int count=0;
   while(*(s++)!=ch)count++;
   return count;
}

int main()
{
int splitpoint;
char *startat;
char theword[64]; 
char part1[30],part2[30]; 
	
 strcpy(theword,"ett|one");
 splitpoint=wheretosplit(theword,'|');
 strncpy(part1,theword,splitpoint);
 part1[splitpoint]=0; //terminate string
 startat=&theword[splitpoint]+sizeof(char);
 strcpy(part2,startat);
 //now, do what you want with the parts
 printf("%s is the same as %s\n",part1,part2);
return 0;
}
taper lawyerMedlem sedan jan. 200481 inlägg
#5

Tack! Nu behöver jag bara lite förklaringar. :)

startat=&theword[splitpoint]+sizeof(char);

Den där raden förstod jag nog inte riktigt. Sedan så har jag problem med att förstå dessa pekare. Varför är t.ex. s i wheretosplit() en pekare?

Tack igen! :)

PeWMedlem sedan juni 20006 839 inlägg
#6

'startat' är en pekare. 'theword' är en sträng. Meningen med 'startat' är att den ska peka på början av resten av strängen 'theword', där skiljetecknet finns. Därav '+sizeof(char)' som då flyttar fram pekningen ett steg till, så att pekaren pekar på själva texten och inte skiljetecknet. &-tecknet behövs för att visa kompilatorn att det är adressen till en specifik position vi vill åt.

Pekaren 's' i wheretosplit använde jag för att det är enkelt att göra så när man räknar sig fram i en sträng. Man skulle även kunna göra det samma genom att indexera (s[count]!=ch) sig fram, men tja.. jag tycker ivf att det är simplare så här och betydligt vackrare. :)

taper lawyerMedlem sedan jan. 200481 inlägg
#7

Tack så mycket för hjälpen! Nu tror jag att jag förstår det mesta. :D
Men +sizeof(char), blir inte det samma sak som +1, eller är jag helt ute och cyklar?

PeWMedlem sedan juni 20006 839 inlägg
#8

Jo visst blir det +1 på plattformar som definierar char som 8 bitars. En ganska bra vana kan ju vara att undvika att låsa sig vid plattformar och istället nyttja sizeof() ;)

Kan ju kanske lägga till att en pekare pekar på en adress och en sträng är en samling data med en startadress som nås av bara variabelnamnet, men när man ska vandra fram i strängen så räknas adressen upp. Detta sker endera direkt genom pekarnotation eller indirekt genom att man anger ett index. Alltså är *(s+42) detsamma som s[42]. Man kan även bli obskyr och skriva 42~~, men det är överkurs.~~

spangoMedlem sedan juni 20006 147 inlägg
#9

PeW skrev:

Jo visst blir det +1 på plattformar som definierar char som 8 bitars. En ganska bra vana kan ju vara att undvika att låsa sig vid plattformar och istället nyttja sizeof() ;)

Enligt ANSI-standarderna för både C och C++ ska typeof(char) alltid ge 1. Hur många system ger andra svar?

PeWMedlem sedan juni 20006 839 inlägg
#10

Okej. Det kanske var ett dåligt exempel med just char eftersom det vanligtvis (betydligt mer vanligt än att int är 32) är 8 bitar men det finns system som har andra specifikationer (!pc-arkitektur) och därför är det rekommenderat att göra som jag gjorde, så har ivf jag blivit lärd. :)

En snabb sökning gav bl.a:

chars are 8 bits on UNIX, 9 on GCOS

http://cm.bell-labs.com/cm/cs/who/dmr/cman.ps

spangoMedlem sedan juni 20006 147 inlägg
#11

Jo, fast hur stor en byte är påverkar inte hur många byte stor en char är. Bitar per byte avspeglas med CHAR_BIT och borde inte påverka sizeof(char). En char är alltid en byte, per definition. Fast det är klart, även om det kanske inte krävs av standarden är sizeof(char) vettigt att använda eftersom det blir konsekvent med annan pekararitmetik (typ när man använder intar eller liknande) och dessutom är det ju inte säkert att alla system faktiskt följer standarden :)

Sang-draxMedlem sedan juli 2002570 inlägg
#12

PeW skrev:

Okej. Det kanske var ett dåligt exempel med just char eftersom det vanligtvis (betydligt mer vanligt än att int är 32) är 8 bitar

Du tänker på något annat. En char kan vara nio bitar, men sizeof(char) är alltid 1, det är en definition.

C++ Standard 5.3.3 (1) skrev:

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1;

Antalet bitar är i detta fall irrelevant.

Sang-draxMedlem sedan juli 2002570 inlägg
#13

spango skrev:

Fast det är klart, även om det kanske inte krävs av standarden är sizeof(char) vettigt att använda eftersom det blir konsekvent med annan pekararitmetik (typ när man använder intar eller liknande) och dessutom är det ju inte säkert att alla system faktiskt följer standarden :)

Nej, faktum är att det blir FEL om man använder sizeof istället för 1. I detta fall hade PeW tur och klarade sig eftersom sizeof(char)==1.

Betänk:

char tal[2] = {1, 2};

char tal1 = *tal;
char tal2 = *(tal + sizeof(char));

printf("%d %d", tal1,tal2);

OK, det fungerade ju bra. Nu testar vi med int istället:

int tal[2] = {1, 2};

int tal1 = *tal;
int tal2 = *(tal + sizeof(int));

printf("%d %d", tal1,tal2);

Den senare koden kommer troligvis att krasha, så använd inte sizeof vid pekararitmetik! Det kommer endast fungera då sizeof(T)==1!

PeW, en pekare till en typ T som ökas med 1, kommer automatiskt av kompilatorn att ökas med sizeof(T).

PeWMedlem sedan juni 20006 839 inlägg
#14

Du har helt rätt Sang-drax. Fel av mig.

taper lawyerMedlem sedan jan. 200481 inlägg
#15

Nu hittade jag en till grej som kanske kan vara bra att veta.

static int wheretosplit(char *s,char ch)

Vad menas med att en funktion är statisk?

PeWMedlem sedan juni 20006 839 inlägg
#16

Det är ett sätt att undvika att funktioner blir globala, dvs hamnar i scope utanför filen. Onödigt i ditt program, men den hamnade där av en för mig gammal vana, som en markering att det är en lokal funktion. Du kan läsa mer om static på funktioner (och även variabler) här.

Genererad på 371 ms · cache AV · v20260730165559-full.f96bc7eb