Limite di traduzione in C

Sto tentando di catturare l’input dell’utente tramite scanf:

char numStrings[5000]; printf("Enter string of numbers:\n\n"); scanf("%s", numStrings); 

Tuttavia, la lunghezza della stringa immessa è di 5000 caratteri. Il limite di traduzione in c99 è 4095 caratteri. Devo dare istruzioni all’utente di interrompere il loro contributo a metà o c’è un lavoro migliore intorno a cui non riesco a pensare?

Devo dare istruzioni all’utente di interrompere il loro contributo a metà o c’è un lavoro migliore intorno a cui non riesco a pensare?

Per quanto riguarda il codice che hai dato, se la parola in ingresso è più lunga di 4999 byte allora puoi aspettarti un buffer overflow. Sì, sarebbe saggio lasciare che qualcuno (ad esempio l’utente o il ragazzo che mantiene questo codice in seguito) sappia che è la lunghezza massima. È bello che tu possa troncare l’input usando un codice come questo: scanf("%4999s" "%*[^ \n]", numStrings); … La direttiva %*[^ \n] esegue il troncamento, in questo caso.

Sarebbe ancora più bello se si potesse far sapere all’utente nel momento in cui si rovescia il buffer, ma scanf non lo rende un compito facile. Cosa sarebbe ancora più bello (per l’utente, intendo) è se si potesse usare l’allocazione dynamic.

Ah, il problema dell’input di dimensioni dinamiche. Se può essere evitato, evitalo. Un metodo comune per evitare questo problema è quello di richiedere input sotto forma di argv , piuttosto che stdin … ma ciò non è sempre ansible, utile o fattibile.

scanf non rende questo problema particolarmente facile da risolvere; infatti, sarebbe molto più facile da risolvere se esistesse una funzionalità simile fornita da %s sotto forma di un’interfaccia simile a fgets .

Senza ulteriore addio, ecco un adattamento del codice che ho scritto in questa risposta , adattato allo scopo di leggere (e contemporaneamente allocare) le parole in una procedura simile a quella dietro %s , piuttosto che le linee in una procedura simile a quella dietro a fgets . Sentiti libero di leggere questa risposta se vuoi saperne di più sull’ispirazione che c’è dietro.

 #include  #include  #include  char *get_dynamic_word(FILE *f) { size_t bytes_read = 0; char *bytes = NULL; int c; do { c = fgetc(f); } while (c >= 0 && isspace(c)); do { if ((bytes_read & (bytes_read + 1)) == 0) { void *temp = realloc(bytes, bytes_read * 2 + 1); if (temp == NULL) { free(bytes); return NULL; } bytes = temp; } bytes[bytes_read] = c >= 0 && !isspace(c) ? c : '\0'; c = fgetc(f); } while (bytes[bytes_read++]); if (c >= 0) { ungetc(c, f); } return bytes; } 

Puoi inserire una stringa molto più grande di quella, lo stack è almeno 1MB nei sistemi operativi comuni, sono 8MB in Linux, quindi questo è il limite effettivo, 1M è 1024KB, quindi potresti provare ad esempio con 512KB che è 524288B

 char string[524288]; scanf("%524287s", string); 

sarà probabilmente ok, se è ancora troppo piccolo, quindi usa malloc() .

No, non è necessario istruire l’utente a separare l’input se supera una determinata lunghezza. Il limite è su stringhe letterali, non su stringhe. Vedere la risposta in questo thread StackOverflow per ulteriori informazioni. Se non si conosce la lunghezza massima ragionevole, si consiglia di utilizzare getline () o getdelim () se il delimitatore che si desidera utilizzare non è un’interruzione di riga.