C - input - συμβολοσειρά απεριόριστου μεγέθους

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: C - input - συμβολοσειρά απεριόριστου μεγέθους

Δημοσίευσηαπό pc_magas » 12 Απρ 2011, 21:52

Λογικά με ένα trhead όπου θα δίνεις ένα ποσοσ χαρακτήρα και 8α το βάζει ένα ένα σε δυναμικό πίνακα με την gerchar() σε ένα loop μέχρι να σου δωθεί \n χαρακτήρας η space ανάλωγως.
Σου έχω μια πρόταση με δυναμική μνήμη:
Σε loop η getchar() διαβάζει ότι έχει ο buffer του stdin άμα βάλει 1000 χαρακτήρες στο buffer σε ένα loop η getchar θα διαβάζει τον επόμενο χαρακτήρα του buffer και δεν θα περιμένει να του δώσεις άλλο χαρακτήρα άρα διαβάζεις γράμμα γράμμα το string και το βάζεις στην κατάλληλη θέση;(Αρκεί να μην γίνει κανα fflush(stdin))
Έτσι εκμεταλέυτικα αυτήν την "αδυναμία" για να διαβάζω ένα string να γράμμα-γράμμα.
Δείτε εδώ
Κώδικας: Επιλογή όλων
#include<stdio.h>
#include<stdlib.h>
char * readstring();
char * readstring()
{
char temp,*s=NULL;
int i=0;
while(1)//8ewritika einai apeiros vrogxos alla den einai sthn pragmatikotita
{
s=(char *)realloc(s,(i+1)*sizeof(char));//auksisi xwrou kata 1 8esi xarakthra
scanf("%c",&temp);//anagnwsi proswrinou xaraktira
if(s!=NULL)//An esei desmeutewi xwros
{
if(temp!='\n')//Oso den vazeis alagi grammis
{

s[i]=temp;//8ese to prosorino xwro gia xarakthres ston pinaka apo string

}
else
{
s[i]='\0';//eidallws termatise to
break;//kai vges apo to loop
}
i++;//auksisi metriti
}
else//An den mporeis na demseuseis xwro
{
break;//vges
}
}
return s;//Epestrepse oti demseuses
}
int main()
{
char *string=NULL;
printf("Enter a string to read\n");
string=readstring();
if(string!=NULL)
{
printf("%s\n",string);
}
}

Έτσι εκεταλευόμενος αυτό διαβάζω string απεριόριστου μήκους!
My blog|Κυπριακή Κοινότητα Ελευθέρου Λογισμικού Λογισμικού ανοικτού Κώδικα
Γνώσεις Linux:Ποτέ αρκετές|Προγραμματισμός: Php, javascript, nodejs, python, bash |Aγγλικά:Καλά
Οι υπολογιστές μου:
Spoiler: show
Ubuntu 16.04 64 bit σεIntel(R) Pentium(R) CPU G4400 @ 3.30GHz, 16Gib Ram, 500Gib Hard Disk, και κάρτα γραφικών Nvidia Geforce GT610
Lubuntu 14.04 σε Dell Inspiron mini 10(1010) intel Atom Z500 1Gb ram και gma500 (εδώθη σε άλλον)
Kubuntu 16.04 Lenovo G70 Intel i5 Nvidia Grapgics Card, Intel Graphics card (έχει 2) με Nouveau, 16Gb RAM, 126GB SSD Σκληρό Δίσκο
Άβαταρ μέλους
pc_magas
powerTUX
powerTUX
 
Δημοσιεύσεις: 2599
Εγγραφή: 12 Απρ 2009, 18:55
Τοποθεσία: Αχαρναί Αττικής
Launchpad: pc_magas
IRC: pc_magas
Εκτύπωση

Re: C - input - συμβολοσειρά απεριόριστου μεγέθους

Δημοσίευσηαπό migf1 » 06 Ιουν 2011, 11:34

Εύκολος τρόπος δεν υπάρχει στη C, μπορείς όμως να το κάνεις όπως σου υπέδειξε ο φίλος simosx παραπάνω, δεσμεύοντας μνήμη δυναμικά όποτε τη χρειάζεσαι.

Πιο συγκεκριμένα, μια υλοποίηση θα μπορούσε να είναι με τη χρήση μιας συνδεδεμένης λίστας χαρακτήρων (linked list) όπου θα διαβάζεις από το πληκτρολόγιο χαρακτήρες π.χ. με το getchar() και για τον καθένα τους θα δημιουργείς και θα προσθέτεις έναν νέο κόμβο (node) στο τέλος της λίστα σου. Αντί για απλή λίστα μπορείς να χρησιμοποιήσεις διπλή λίστα (double linked list), στοίβα (stack), ουρά (queue) ή οποιαδήποτε άλλη δομή δεδομένων, ανάλογα με τις ανάγκες του προγράμματός σου στη διαχείριση του string αυτού.

medigeek έγραψε:Ναι αυτό το γνωρίζω, το πρόβλημα με το scanf είναι ότι σταματάει στο πρώτο space χαρακτήρα. Άσε που περιορίζεται σε συγκεκριμένο αριθμό χαρακτήρων πριν το compile.

Αυτό που θα ήθελα είναι:
έγραψε:Αυτό που κάνεις είναι δυναμικά ζητάς τη μνήμη που χρειάζεται.


Είναι υποθετική περίπτωση, δεν το χρειάζομαι προσωπικά ούτε για δουλειά, απλά με ενδιαφέρει αν γίνεται να υπάρχει κάτι το ίδιο με αυτό στο python: να δέχεται input χαρακτήρες επ' απειρον (απειρο εννοώ μέχρι σ'ένα σημείο, λόγω μνήμης ή όπως είπες στο μέγιστο αριθμό χαρακτήρων που επιτρέπει το MAX_LENGTH του τερματικού).

Δηλαδή το size_t θα δημιουργήσει πρόβλημα;
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: C - input - συμβολοσειρά απεριόριστου μεγέθους

Δημοσίευσηαπό migf1 » 06 Ιουν 2011, 17:54

Σου παραθέτω κώδικα για το διάβασμα και το τύπωμα string άπειρου μήκους, υλοποιημένο με απλή συνδεδεμένη λίστα (single linked list).

Όπου "Inf" ή "inf" φαντάσου "Infinite" (άπειρο).

Κώδικας: Επιλογή όλων

#include <stdio.h>
#include <stdlib.h>

typedef enum { FALSE=0, TRUE } Bool;

typedef struct InfString {
int c;
struct InfString *next;
}InfString;

/* ------------------------------------------------------------------
* Insert c at the end of sinf
*/
Bool sinf_inslast( InfString **sinf, int c )
{
InfString *head = NULL, *dummy = NULL;
InfString *new = calloc(1, sizeof(struct InfString) );
if ( !new )
return FALSE;

new->c = c;
new->next = NULL;

if ( !*sinf ) {
*sinf = new;
return TRUE;
}

head = dummy = *sinf;
while ( head ) {
dummy = head;
head = head->next;
}
dummy->next = new;

return TRUE;
}

/* ------------------------------------------------------------------
* Read sinf from stdin until '\n' is pressed
*/
InfString *sinf_get( InfString **sinf )
{
int c;

while ( (c=getc(stdin)) != '\n' )
if ( !sinf_inslast( sinf, c ) )
break;

return *sinf;
}

/* ------------------------------------------------------------------
* Print sinf on the screen
*/
void sinf_print( InfString *sinf )
{
if ( !sinf )
return;

while ( sinf ) {
putchar( sinf->c );
sinf = sinf->next;
}

return;
}

/* ------------------------------------------------------------------
* Free memory reserved for sinf
*/
void sinf_destroy( InfString **sinf )
{
if ( !*sinf )
return;

InfString *dummy = NULL;
while ( *sinf ) {
dummy = *sinf;
*sinf = (*sinf)->next;
free( dummy );
}

return;
}

/* ------------------------------------------------------------------
*
*/
int main( void )
{
InfString *sinf = NULL;

puts("Type your string (infinite length):");
fflush(stdin);
sinf_get( &sinf ); // read sinf (memory is reserved dynamically on demand)

puts("\nYou typed:");
sinf_print( sinf ); // print sinf

putchar('\n');

sinf_destroy( &sinf ); // free memory reserved for sinf

printf("\npress ENTER to exit..."); fflush(stdin); getchar();
exit(0);
}

Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Προηγούμενη

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι