Sträng i C

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46935
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Sträng i C

Inlägg av TomasL »

Det finns väll en ganska stor skillnad, sodjan har med const i sin version.
Vissa kompilatorer kräver det, till exempel MCC18.
Eftersom det är en konstant och inget annat.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Sträng i C

Inlägg av jesse »

Alla pekare måste inte vara konstanter. Det är väl ganska vanligt att man låter en pekare peka runt på olika objekt, t.ex. när man ska loopa igenom en lista eller en textsträng. Sen är det en annan sak att det ofta är praktiskt att behålla enpekare till första tecknet i strängen... Det kan vara svårt att hitta senare, annars.
wapper
Inlägg: 40
Blev medlem: 8 augusti 2012, 02:37:53

Re: Sträng i C

Inlägg av wapper »

Du kan även använda funktionen sprintf.

Kod: Markera allt

#include <stdio.h>

sVarabel = sprintf("TEXT SOM SKRIVS");
lcd_puts(&sVarabel);

sVarabel = sprintf("Varvtal: %d RPM", rpm);
lcd_puts(&sVarabel);
Formatkoderna till sprintf är som följer:

%c character
%d signed integers
%i signed integers
%e scientific notation, with a lowercase "e"
%E scientific notation, with a uppercase "E"
%f floating point
%g use %e or %f, whichever is shorter
%G use %E or %f, whichever is shorter
%o octal
%s a string of characters
%u unsigned integer
%x unsigned hexadecimal, with lowercase letters
%X unsigned hexadecimal, with uppercase letters
%p a pointer
%n the argument shall be a pointer to an integer into which is placed the number of characters written so far
%% a '%' sign
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46935
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Sträng i C

Inlägg av TomasL »

Det är en jäkla skillnad om man får en sträng som variabel, till exempel över seriporten, eller skriver texten i koden.
Är texten skriven i koden så är det en konstant per definition, följaktligen måste const vara med, och i fallet MCC18 även ROM, så:
char string[] = "this is a string"; //genererar fel i MCC18
char string[] = "this is a string"; //genererar fel i MCC18
const char string[] = "this is a string"; //genererar fel i MCC18
const rom char string[] ="this is a string"; //är ok i MCC18
Användarvisningsbild
Odur
Inlägg: 267
Blev medlem: 11 september 2005, 14:36:49
Ort: Borås

Re: Sträng i C

Inlägg av Odur »

Jag har aldrig använt MCC18 så jag får tro dig på ditt ord. Men det är ju knepigt implementerat då. Att initialt deklarera och initiera en sträng, eller någon annan variabel, är ju oerhört vanligt.

Men ska man använda MCC18 så får man väl leva med det.

Nån som vet hur XC8/16/32 beter sig? Jag tänkte börja kika på dom snart.
Användarvisningsbild
AndLi
Inlägg: 18254
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Sträng i C

Inlägg av AndLi »

char string[] = "this is a string"; //genererar fel i MCC18

Vilken skum kompilator, vad anser den vara fel? Mot vilken "standard" går den?

Hur vill den att man ska göra för att få en array av char med strängen i där man kan editera strängen?

Gcc (open source jag vet, den kan ju inte göra rätt...) släpper såklart igenom det där utan problem, även andra kompilatorer så som IARs brukar inte gnälla..
Användarvisningsbild
bit96
Inlägg: 2528
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: Sträng i C

Inlägg av bit96 »

Det här med const i C kan betyda lite olika beroende på var i deklarationen man skriver det.

Nu kan jag inte redogöra för exakt hur just MCC18 vill ha det, men

Kod: Markera allt

const rom char string[] ="this is a string"; //är ok i MCC18
borde betyda att string kan ändras, d.v.s. själva pekaren kan fås att peka på annat, men textmassan i sig kan inte modifieras.

Vill man även "låsa" pekaren som en konstant borde ytterligare ett const stoppas in.
Jag är dock osäker på hur när [] används, det är lättare med *
Kanske man kan skriva:

Kod: Markera allt

const rom char * const string= "this is a string";
Jag undrar om TS blev klokare av det här :wacko:
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Sträng i C

Inlägg av jesse »

OK, då är jag med.

Vad jag saknar i C är ett sätt att tilldela en sträng en text. Det går att deklarera variabeln (som då blir konstant) som

char foo[] = "abc";
printf(foo);

men jag kan inte göra som jag minns man gjorde i BASIC:

char foo[100], bar[10];
foo = "abc";
foo = "abc" + "def";
foo = bar;
foo = foo + bar + ".exe";
foo = "abc + int_to_string(int_val) + "def";

Det hade varit mycket praktiskt. Finns det nån smart preprocessor och/eller bibliotek för sådant i C?
(Ja, det finns ju string.h men den tycker jag är relativt klumpig jämfört med ovanstående)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46935
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Sträng i C

Inlägg av TomasL »

nej, du får göra en strcpy, eller nått liknande
Användarvisningsbild
Krille Krokodil
Inlägg: 4062
Blev medlem: 9 december 2005, 22:33:11
Ort: Helsingborg

Re: Sträng i C

Inlägg av Krille Krokodil »

Definierar man det som char string[] ="abc" så är string ingen pekare utan bara ett fältnamn med en fast adress.

jesse: C++ som gäller om man skall kunna göra så med strängar.
Användarvisningsbild
bit96
Inlägg: 2528
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: Sträng i C

Inlägg av bit96 »

jesse:
Nej i C kan man inte 'plussa' ihop strängar som man kunde i BASIC.
Man får använda funktioner i string.h som strcpy(), strncpy(), strcat() o.s.v.
Eller skriva egna funktioner, det är ju egentligen ganska enkla block-copy-funktioner av olika slag.

Fördelen med detta är att man vet vad som händer ner på bytenivå. Man vet hur mycket(litet) minne som går åt och kompilatorn kan direkt översätta till en maskinkodsoperation för block-transfer för de CPU:er som stödjer detta.
Det skapas heller ingen "onödig" kod i 'bakgrunden' som kollar att strängarna finns, hur långa de är, att de är korrekta m.m.

Nackdelen är att det är inte lika enkelt som i BASIC och det tar en stund att lära sig.
Det skapas heller ingen "idoitsäker" kod i 'bakgrunden' som kollar att strängarna finns, hur långa de är, att de är korrekta m.m. :)
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Sträng i C

Inlägg av jesse »

>Det skapas heller ingen "idoitsäker" kod...

Då är det ju som vanligt i C med andra ord. :D
Användarvisningsbild
kimmen
Inlägg: 2042
Blev medlem: 25 augusti 2007, 16:53:51
Ort: Stockholm (Kista)

Re: Sträng i C

Inlägg av kimmen »

Angåend skillanden mellan char test1[] = "korvbil A"; och char * test2 = "korvbil B"; blir det en skillnad:

Koden

Kod: Markera allt

int main(int argc, char* argv[])
{
	char test1[] = "korvbil A";
	char * test2 = "korvbil B";
	char * test3 = test1;
	//char test4[] = test2; // Ej tillåtet

	printf("test1: %s, sizeof(test1) = %d\n", test1, (int)sizeof(test1));
	printf("test2: %s, sizeof(test2) = %d\n", test2, (int)sizeof(test2));
	printf("test3: %s, sizeof(test3) = %d\n", test3, (int)sizeof(test3));

	return 0;
}
ger utskriften

Kod: Markera allt

test1: korvbil A, sizeof(test1) = 10
test2: korvbil B, sizeof(test2) = 4
test3: korvbil A, sizeof(test3) = 4
.

Gör man sizeof på en array får man storleken av alla element tillsammans, men för en pekare blir det pekarens storlek. Arrayer går ju att omvandla till pekare utan att casta, så skillnaden märks inte så ofta. :)

edit: En annan skillnad här är att test2 blir en pekare till en strängliteral, och därför får man inte skriva till den enligt standarden. test1 är däremot en lokal array som är initierad med strängen "korvbil A", och den får man ändra i.

I en typisk implementation skulle array-strängen kunna skrivas till stacken på något sätt, medan den andra skulle kunna hamna i ROM med en pekare till det.
Användarvisningsbild
JonasJ
Inlägg: 653
Blev medlem: 11 september 2007, 16:02:26
Ort: Kinna
Kontakt:

Re: Sträng i C

Inlägg av JonasJ »

En bra källa för sådana här typer av frågor är FAQ för comp.lang.c.

Här står det:

Kod: Markera allt

 Q: What is the difference between these initializations?

char a[] = "string literal";
char *p  = "string literal";

My program crashes if I try to assign a new value to p[i].

A: A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways:

    As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values of the characters in that array (and, if necessary, its size).
    Anywhere else, it turns into an unnamed, static array of characters, and this unnamed array may be stored in read-only memory, and which therefore cannot necessarily be modified. In an expression context, the array is converted at once to a pointer, as usual (see section 6), so the second declaration initializes p to point to the unnamed array's first element. 

Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching).

See also questions 1.31, 6.1, 6.2, 6.8, and 11.8b. 
Skriv svar