Quali sono i dettagli della definizione di una stringa in C?


10

Dovrei rispondere a una domanda a casa per una delle mie lezioni. In particolare, dovrei dire se alcuni array in C sono considerati stringhe o meno. Sulla base di questo articolo ( https://www.geeksforgeeks.org/strings-in-c-2/ ) So che le stringhe sono un array di caratteri con il terminatore null alla fine.

Il mio blocco principale è una parte della domanda che si pone su un array che assomiglia a questo:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

Questo è ovviamente un array di caratteri con un carattere che termina null alla fine. Tuttavia, è ancora considerata una stringa poiché ha anche un carattere di terminazione null nel mezzo? Come influirà sulla stringa?

EDIT: sulla base dei commenti, ho fornito la formulazione effettiva della domanda:

"Quale delle seguenti matrici può essere considerata" stringhe "allo scopo di usarle come argomenti per strcpy (), strncpy (), strcmp (), strncmp () e funzioni stringa simili (indica tutte le applicazioni)?"

EDIT: ho inviato un'email al mio professore a riguardo poiché la domanda sembrava formulare ambiguamente (come sottolineato da diverse persone). Se qualcuno è curioso, mi ha detto "Sì, è una stringa. La chiave è che c'è un carattere nullo. Ma ovviamente ciò avrà effetto su qualsiasi operazione di stringa; la stringa termina con il carattere null".


4
Si potrebbe dire che è la stringa "CS"con qualche byte di garbage aggiunto (nel qual caso il carattere NUL finale è irrilevante). Ma non è una stringa "nel suo insieme". - Tuttavia, alimentare questo strcpyecc. Non farà esplodere il tuo PC perché queste funzioni "vedranno" solo la "CS"parte.
— Hagen von Eitzen,

2
c1 può assolutamente essere usato come argomento per strcmp(). Se può essere usato come argomento per la mutazione delle funzioni di stringa dipende da fattori aggiuntivi che non vengono forniti.
— EOF

2
I contenuti di c1sono mutabili, quindi non vedo perché non possa essere un argomento di destinazione valido strcpyo simile, a meno che non sia abbastanza grande da contenere la stringa di origine. Ciò non farebbe in modo che non sia una stringa, ma non adatta a un determinato scopo.
— John Bollinger,

1
Nel complesso, concordo sul fatto che la domanda sia formulata in modo ambiguo. L'espressione c1soddisferebbe i requisiti di base per gli argomenti di stringa a tutte le funzioni di stringa (strette) della libreria standard, comprese tutte quelle specificatamente denominate, ma il comportamento potrebbe non essere quello che il chiamante si aspetta o desidera (ignorando anche comportamenti indefiniti che potrebbero essere suscitati).
— John Bollinger,

1
Si noti che il tipo non deve essere char. Qualsiasi tipo di carattere lo farà.
— chux - Ripristina Monica il

Risposte:


8

c1è principalmente [1] equivalente &c1[0], che regge una stringa, "CS".

C'è una seconda stringa in agguato in là, "324", a partire &c1[3]- ma finché si accede c1come c1, la stringa "CS"è tutte le funzioni strcpy()et al. vorrei vedere.


[1]: c1è un array, &c1[0]è un puntatore.


Quindi, è corretto utilizzare c1come stringa di destinazione in un strcpy()comando? La domanda è ambigua, nella migliore delle ipotesi.
— Andrew Henle,

1
Ovviamente potresti usare c1entrambi gli argomenti per strcpy(). È una corda perfettamente ordinaria in tutti i sensi. Le stringhe ordinarie spesso contengono spazzatura residua dopo i loro terminatori. Il fatto che questa immondizia sia codificata nel programma dà l'impressione che l'autore abbia intenzione di utilizzare c1in modi non stringa, ma questo non faceva parte della domanda.
— Lee Daniel Crocker,

" c1equivale a &c1[0]" inganna. c1è un array. &c1[0]è un puntatore.
— chux - Ripristina Monica il

2

Se vuoi conoscere i dettagli della definizione di una stringa in C, vai alla fonte.

Dallo standard C90 :

7 Biblioteca

7.1 Introduzione

7.1.1 Definizioni dei termini
Una stringa è una sequenza contigua di caratteri terminata da e incluso il primo carattere null. Un "puntatore a" una stringa è un puntatore al suo carattere iniziale (indirizzato più in basso). La "lunghezza" di una stringa è il numero di caratteri che precedono il carattere null e il suo "valore" è la sequenza dei valori dei caratteri contenuti, in ordine.

(Non ci sono stati cambiamenti rilevanti negli standard successivi.)

Pertanto, c1contiene due stringhe consecutive, "CS" e "324", ma non è essa stessa una stringa.

Se passiamo un array a una funzione, decade a un puntatore al suo primo elemento, quindi +c1punta a una stringa (la prima), che è abbastanza buona per qualsiasi funzione che si aspetta un puntatore a stringa. Non punta a una stringa "CS \ 0324", ma probabilmente è abbastanza buona per la domanda dei tuoi istruttori, il che è ambiguo.


4
Direi che anche con questa definizione, c1 è chiaramente la stringa "CS". Periodo. Il fatto che possa contenere byte diversi da zero dopo il terminatore è irrilevante: molte stringhe saranno così durante la loro vita.
— Lee Daniel Crocker,

+c1punta a una stringa, perché c1inizia con una stringa. c1Tuttavia , in nessun modo, forma o forma formano una stringa.
— Deduplicatore il

2
È l'indirizzo di una sezione della memoria che contiene alcuni caratteri terminati da un byte zero. Se printf () andasse bene con un% s, darebbe un numero perfettamente buono passato a strlen (), funzionerebbe se passato a strcpy (), ecc. Mi sembra una stringa.
— Lee Daniel Crocker,


Ovviamente. Ma gli array possono certamente essere stringhe.
— Lee Daniel Crocker,

0

Aggiungendo alla risposta di @S devSolar, qualcosa che ho scoperto dopo aver giocato con la stringa data, se dovesse essere:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

Se si genera questa stringa, si otterrà CS03240e la dimensione di questa stringa è 7. Per quanto ne so, \\0viene utilizzato per indicare il carattere null ( es. \0 ). Se fate:

printf("\0");

Non vedi nulla nel registro di output, ma se lo fai:

printf("\\0");

Vedi a \0 , qualcosa che ci si aspetta perché per generare caratteri speciali come barre rovesciate o virgolette, devi usare un \insieme a loro.

Qualcosa che mi confonde è l'output CS03240 e la sua dimensione 7. È risaputo che la dimensione di una stringa è il numero di caratteri in essa più uno (per il carattere null). Inoltre, la dimensione è 7 anche per la stringa char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };.

Quindi forse un seguito a questa domanda, cosa sta succedendo qui?


1
'\\0'non è un carattere nullo . È una costante multi-carattere. Ha un valore definito di implementazione sicuramente al di fuori dell'intervallo di char. c1[]non è una stringa in quanto manca di un carattere null . "hai generato questa stringa" probabilmente si traduce in un comportamento indefinito .
— chux - Ripristina Monica il

Non ti ho capito esattamente anche se ho cercato costanti multi-personaggio. Se c1 [] non è una stringa perché non ha un carattere null alla fine, allora perché la dimensione viene visualizzata come 7 nel caso iniziale come pubblicata dall'OP?
— rasengan__

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };è di dimensione 7 perché è inizializzato con 7 valori. Le sue dimensioni non hanno nulla a che fare con le stringhe . char c1[] = { 1, 2, 3, 4, 5, 6, 7 };lo renderebbe comunque di taglia 7.
— chux - Ripristina Monica il

Quanto all'array c1contiene una puntura? Questo è un problema separato. Vedi anche
— chux - Ripristina Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.