Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta
Google ha appena rinnovato la sua celebre serie A con il Pixel 10a, lo smartphone della serie più conveniente se consideriamo il rapporto tra costo e prestazioni. Con il chip Tensor G4, un design raffinato soprattutto sul retro e l'integrazione profonda di Gemini, il colosso di Mountain View promette un'esperienza premium a un prezzo accessibile. E il retro non ha nessuno scalino
6G, da rete che trasporta dati a rete intelligente: Qualcomm accelera al MWC 2026
6G, da rete che trasporta dati a rete intelligente: Qualcomm accelera al MWC 2026
Al MWC Qualcomm annuncia una coalizione industriale per lanciare il 6G entro il 2029 e introduce agenti IA per la gestione autonoma della RAN. Ericsson, presente sul palco, conferma la direzione: le reti del futuro saranno IA-native fin dalla progettazione
CHUWI CoreBook Air alla prova: design premium, buona autonomia e qualche compromesso
CHUWI CoreBook Air alla prova: design premium, buona autonomia e qualche compromesso
CHUWI CoreBook Air è un ultraleggero da 1 kg con Ryzen 5 6600H, display 14" 16:10 e 16 GB LPDDR5. Offre buona portabilità, autonomia discreta e costruzione in alluminio, ma storage PCIe 3.0 e RAM saldata limitano l'espandibilità. A 549 euro sfida brand più noti nella stessa fascia di mercato.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 03-08-2009, 16:01   #1
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
[C] Problema nel ritorno di una stringa

Giorno a tutti, stò scrivendo un piccolo parser e tra i vari passi da seguire c'è quello di rimuovere i commenti e gli spazi bianchi (in modo da poter effettuare token senza problemi dei blank spaces).

Semplificando la funzione incriminata ho ricostruito il programma con la singola funzione e un main che la richiama.
L'algoritmo è molto semplice: tramite una switch inserita in una for che cicla i caratteri della riga elimina tabulazioni, blank spaces, e commenti.

Per verificare il funzionamento dell'algoritmo in sè ho modificato il programma facendogli direttamente mostrare i caratteri della stringa che non siano i suddetti da eliminare e tutto viene mostrato correttamente.
escaping2.c (codice funzionante ma non è ciò che mi serve - esegue solo l'algoritmo)
Codice PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void EscapeStringchar *source )
{
    
unsigned int i
    
unsigned int isCommentLine 0/*on 1 the line will be discarded - is a comment line*/
    //char *bufString;
    
for( 0strlen(source); i++ )
    {
        switch( 
source[i] )
        {
            case 
'\t':
            case 
' ' :
                break;
            case 
'#' :
                
isCommentLine 1;
                break;
            default  :
                
printf("%c"source[i]);
                break;
        }
        if(
isCommentLine/* != 0"*/
        
{
            return;
        }
    }
    return;
/*EscapeString*/

int main()
{
    
char *string "this is a string #and this is a comment that will not show.";
    
EscapeString(string);
    return 
0;

Ma se invece voglio raccogliere in una stringa i caratteri non riesco proprio.
Ottengo sempre un segmentation fault e gdb si blocca sulla chiamata alla funzione, quindi è quella che non lavora a dovere.
Ora mostro lo stesso algoritmo che dovrebbe ritornare la stringa:
blank.c (segmentation fault)
Codice PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CRLF
static char *EscapeStringchar *source )
{
    
unsigned int i
    
unsigned int isCommentLine 0/*on 1 the line will be discarded - is a comment line*/
    
char *bufString;
    for( 
0strlen(source); i++ )
    {
        switch( 
source[i] )
        {
            case 
'\t':
            case 
' ' :
                break;
            case 
'#' :
                
isCommentLine 1;
                break;
            default  :
                
bufString += source[i];
                break;
        }
        if(
isCommentLine/* != 0"*/
        
{
            return 
bufString;
        }
    }
    return 
bufString;
/*EscapeString*/

int main()
{
    
char *String "this is a string #and this is a comment that will not show.";
    
char *escapedString EscapeString(String);
    
printf("%s" CRLFescapedString);
    return 
0;

Premetto che una volta risolto questo problema la funzione userà questo prototipo:
static char *EscapeString( char *dest, char *source );
in modo da accettare come input anche la stringa in cui conservare la stringa elaborata ed evitare di scrivere questo poco elegante: char *escapedString = EscapeString(string); ma il problema è lo stesso.

Ringrazio chiunque saprà dirmi cosa sbaglio... è da sabato che ci sto lavorando sopra e ho spulciato tutto google ma non ne sono venuto a capo.
Ps. Ho provato con strcat e strcpy lavorando sui puntatori, ma stesso risultato.
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 16:14   #2
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Quel
Codice:
                bufString += source[i];
purtroppo non esiste in C. Devi usare l'allocazione dinamica della stringa (ergo: malloc() e realloc()) e concatenare con strcat(), o aggiungere un carattere alla volta.
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 16:24   #3
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Quel
Codice:
                bufString += source[i];
purtroppo non esiste in C. Devi usare l'allocazione dinamica della stringa (ergo: malloc() e realloc()) e concatenare con strcat(), o aggiungere un carattere alla volta.
Lol imperdonabile errore.
Riguardo all'utilizzo di malloc() avevo già provato a effettuare un bel
Codice PHP:
char *bufString malloc(sizeof(source)); 
calcolando una lunghezza massima pari alla stringa di input (dato che si và a sottrarre non ad addizionare altri caratteri)
e poi usare strcat(bufString, source[i]) nel blocco default.
Ma ovviamente strcat si aspetta una puntatore costante di tipo char (const char *src).
Eseguo quindi il cast come segue:
Codice PHP:
strcat(bufString, (char *)source[i]); 
Ma il compilatore mi segnala un errore di tipo: warning: cast to pointer from integer of different size.
E indovina un po' ?
Segmentation fault. Sò qual'è il problema ma non son riuscito a risolverlo e tra i tanti test avevo testato quel +=.

Mille grazie per l'attenzione!
Ciao e buona giornata.
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 16:54   #4
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Aspetta aspetta, qui stai facendo un po' di confusione e ti capisco, i puntatori fanno girare la testa a molti.

Allora, per calcolare la lunghezza in caratteri di una stringa non usare sizeof(p), dove p è il puntatore alla stringa. La grandezza esatta la trovi con:
Codice:
size_t uSize = (strlen(source) + 1) * sizeof(char);
Ovvero, un'area di memoria grande tanto quanto la grandezza di un singolo char (dato dal sizeof()), moltiplicata per la lunghezza della stringa originaria (data da strlen()) più uno (per il terminatore di stringa). Se usi semplicemente sizeof(source) otterrai sempre l'equivalente di sizeof(char *), perché quello è il tipo di source. Una cosa simile funzionerebbe soltanto su un'array di char.

Poi, strcat() si occupa di concatenare due stringhe, ma tu la chiami su una stringa e su un carattere (rispettivamente, char* e char), il che non è la stessa cosa. Per copiare solo un carattere nella stringa, ti consiglierei lavorare su di un indice e salvare il carattere che vuoi man mano che ti serve, abbozzo un po':
Codice:
char *sNewString = /* allocazione */;
unsigned uIndex = 0;

while (/* scansiona la stringa originale */)
{
    if (/* il carattere c è quello giusto */)
    {
        sNewString[uIndex++] = c;
    }
}
Insomma, puoi accodare così ogni nuovo carattere nella stringa.

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!

Ultima modifica di DanieleC88 : 03-08-2009 alle 16:57.
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 18:35   #5
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Aspetta aspetta, qui stai facendo un po' di confusione e ti capisco, i puntatori fanno girare la testa a molti.

Allora, per calcolare la lunghezza in caratteri di una stringa non usare sizeof(p), dove p è il puntatore alla stringa. La grandezza esatta la trovi con:
Codice:
size_t uSize = (strlen(source) + 1) * sizeof(char);
Ovvero, un'area di memoria grande tanto quanto la grandezza di un singolo char (dato dal sizeof()), moltiplicata per la lunghezza della stringa originaria (data da strlen()) più uno (per il terminatore di stringa).
Hai perfettamente ragione, ho commesso un'errore, ma adesso che me lo hai chiarito spero di non commetterlo in seguito.
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Se usi semplicemente sizeof(source) otterrai sempre l'equivalente di sizeof(char *), perché quello è il tipo di source. Una cosa simile funzionerebbe soltanto su un'array di char.
E qui si ho fatto un'errore coi puntatori, nel senso che io pensavo che essendo un char *name; un puntatore a una locazione di memoria che contiene una sequenza di char (come del resto gli array), una cosa simile avrebbe funzionato anche sul puntatore (che, forse erroneamente, pensavo si riferisse a un'array di char).
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Poi, strcat() si occupa di concatenare due stringhe, ma tu la chiami su una stringa e su un carattere (rispettivamente, char* e char), il che non è la stessa cosa. Per copiare solo un carattere nella stringa, ti consiglierei lavorare su di un indice e salvare il carattere che vuoi man mano che ti serve, abbozzo un po':
Codice:
char *sNewString = /* allocazione */;
unsigned uIndex = 0;

while (/* scansiona la stringa originale */)
{
    if (/* il carattere c è quello giusto */)
    {
        sNewString[uIndex++] = c;
    }
}
Insomma, puoi accodare così ogni nuovo carattere nella stringa.

ciao
Qui non mi è molto chiaro. Strcat() effettua una concatenazione. Prende due stringe in input ok, ma se una stringa fosse di un solo char dovrebbe funzionare lo stesso no? Quindi effettuando un cast all'ultimo secondo su un tipo char mi aspettavo funzionasse, ma evidentemente benchè l'abbia castata a char * non la riconosce come stringa ma come singolo carattere. Ed ora capisco anche a cosa si riferiva quell'errore che diceva casting to pointer from integer of different size.

Beh adesso provo il metodo che mi hai consigliato per lavorare su un singolo char alla volta.

Mille grazie e buona serata!
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 18:53   #6
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Il tuo dubbio ulla strcat() viene dal fatto che in C non esiste un "tipo stringa", ma una stringa è semplicemente definita da un'area di memoria contenente dei caratteri e terminata da un carattere speciale (uno '\0'). Quindi un carattere singolo NON è una stringa: una stringa C contenente un solo carattere è in realtà una sequenza di due caratteri (il carattere più il terminatore).

Le funzioni standard del C che lavorano sulle stringhe presuppongono che ciò che ricevono in input sia un puntatore ad una stringa terminata da '\0'. Se non viene mai incontrato il terminatore, puoi sforare e leggere memoria inesistente o a cui non dovresti avere accesso. Il semplice cast da carattere a puntatore di caratteri significa che otterrai un puntatore con indirizzo pari al valore del carattere (quindi tra 0 e 255 inclusi), e non la memoria che ti aspetteresti.
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 19:24   #7
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Bene, più o meno mi è chiaro. Nel senso che ho capito quello che hai detto, ma dato che l'unica differenza (come hai specificato, entrambe terminano con \0) è la sequenza di caratteri, non capisco perchè le funzioni che accettano le stringhe non l'accettano. Infondo sarebbe come dichiarare:
char *ciao = "a";
char ciao = "a";
char ciao[4] = "a";
tutte e tre sono viste come a\0 no?
Capisco il fatto del puntatore e che punta a una memoria di un singolo char, ma proprio a livello di memoria non capisco cosa cambia. char *ciao = "a" viene riconosciuta dalle funzione che accettano la stringa e char ciao = "a" no. Se non si basasse sul riconoscimento dei tipi, potrebbe accettarle senza problemi mi pare. Capisco che è cosi e boh (soprattutto poichè appunto si basa sul riconoscimento dei tipi) ed è un linguaggio molto vecchio (e quindi non una cosa fatta male) ma mi rimane sto chiodo fisso solo per pura curiosità. Il resto l'ho perfettamente capito .
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 19:30   #8
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Quote:
Originariamente inviato da Y3PP4 Guarda i messaggi
Infondo sarebbe come dichiarare:
char *ciao = "a";
char ciao = "a";
char ciao[4] = "a";
tutte e tre sono viste come a\0 no?
Il primo e il terzo sì, il secondo no. Perché "a" diventa effettivamente "a\0", quindi una stringa definita in memoria e composta da due caratteri. Ora, per quel che ti ho spiegato prima, il compilatore assegna a ciò che sta a sinistra dell'assegnazione il puntatore alla stringa, ma nel secondo caso il tipo della variabile è char, ovverosia un valore intero di 1 byte (e non di 4 byte come sono i puntatori nelle architetture x86 a 32 bit), perciò si rifiuta di farlo senza segnalarti (giustamente) un errore. Non volevo scendere così "in basso" per spiegarti l'errore.

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 19:41   #9
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Oh, finalmente mi è chiaro.
Mi spiace averti portato via così tanto tempo, ma a me non piacciono i dogmi e vorrei capire le varie cose, sia per curiosità sia perchè entrando nell'ottica che sta alla base di un ragionamento non solo riesco ad applicarlo meglio, ma riesco a ricordarlo con facilità e non si dimentica nel tempo.
Un po' come la matematica: se un esecizio ti viene spiegato con tanto di perchè delle operazioni lo ricordi meglio e più facilmente di quello in cui ti danno la formula e basta.



Mille grazie e buona serata.
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 03-08-2009, 19:45   #10
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Figurati, fai strabenissimo a "scavare" per capire bene le cose. Non mi hai rubato tempo, altrimenti non ti avrei risposto...
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta Recensione Google Pixel 10a, si migliora poco ma...
6G, da rete che trasporta dati a rete intelligente: Qualcomm accelera al MWC 2026 6G, da rete che trasporta dati a rete intelligen...
CHUWI CoreBook Air alla prova: design premium, buona autonomia e qualche compromesso CHUWI CoreBook Air alla prova: design premium, b...
Roborock Saros 20: il robot preciso e molto sottile Roborock Saros 20: il robot preciso e molto sott...
ASUS ROG Kithara: quando HIFIMAN incontra il gaming con driver planari da 100mm ASUS ROG Kithara: quando HIFIMAN incontra il gam...
Annunciano il recupero di 4,8 milioni di...
Oggi degli ottimi auricolari Sony con ca...
Muffa in casa? Questo deumidificatore da...
Sonos Era 100: il punto d'ingresso per u...
"Non stiamo sostituendo nessuno con...
Tutti i robot in offerta ora: prezzi bas...
Fra 3 giorni, a mezzanotte, Amazon attiv...
Il principale limite del MacBook Neo &eg...
899€ in tutti i colori, crolla il prezzo...
Sempre più pubblicità su Y...
Costo della memoria alle stelle? Non ave...
GPT-5.4 cambia il modo di usare ChatGPT:...
Centinaia di petabyte in una molecola: l...
Lenovo al MWC 2026: dal PC modulare all'...
Huawei presenta gli agenti di IA per le ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 11:42.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v