Τα πάντα για την C

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

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

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 15 Φεβ 2012, 22:10

Το κατάλαβα το θέμα που έχει.... Την δουλείτσα του την κάνει κανονικά
απλα αν δώσω πχ ένα string

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


και αλλο ένα

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


Τοτε θα πάρω κάτι σε στυλ ->

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


Αντιγράφησαν οσες θέσεις προυπήρχαν και όσες δεν καλύπτονται απο το αρχικό string
μένουν ως έχουν.

Το έλυσα με αυτο ->

Κώδικας: Επιλογή όλων
while( s1[i] || s2[i] != '\0' )


και τωρα παω να το προσπαθησω και με δεικτες :)
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 15 Φεβ 2012, 22:40

Star_Light έγραψε:Δηλαδη αυτο που ηθελα να κάνω δεν γινοταν με απλούς δείκτες? Πρεπει να χρησιμοποιήσω διπλους?

Κοίτα, είτε δουλεύει είτε δεν δουλεύει, με ή χωρίς διπλούς δείκτες, είναι αδιάφορο διότι έτσι κι αλλιώς είναι αδύνατον να εναλλάξεις στατικά strings διαφορετικού μέγιστου μήκους (τα έχουμε ξαναπεί όπως θυμάσαι).

Τα στατικά strings (όπως και οι στατικοί πίνακες) έχουν fixed μέγιστο μήκος το οποίο δεν αλλάζει ότι και να κάνεις. Επίσης τα ονόματα-δείκτες των στατικών strings (όπως και των στατικών πινάκων) είναι κι αυτά fixed, που σημαίνει πως δεν μπορούν να χρησιμοποιηθούν ως LVALUES. Εν ολίγοις, είναι αδύνατον να εναλλάξεις 2 στατικά strings (ή πίνακες) διαφορετικού μέγιστου μήκους.

Εντύπωσέ το! :P

Αυτό που μπορείς να κάνεις με τα στατικά strings είναι τα ορίσεις με ίδιο μέγιστο μήκος, και να εναλλάξεις ότι περιέχουν στο τρέχον μήκος τους (το οποίο μπορεί να διαφέρει) και προφανώς πρέπει η ρουτίνα σου να λαμβάνει υπόψη της ποιο από τα 2 strings έχει το μικρότερο τρέχον μήκος, ώστε να διαχειριστείς και τους χρακτήρες που θα περισσεύουν από το άλλο string.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 15 Φεβ 2012, 23:06

migf1 έγραψε:
Κοίτα, είτε δουλεύει είτε δεν δουλεύει, με ή χωρίς διπλούς δείκτες, είναι αδιάφορο διότι έτσι κι αλλιώς είναι αδύνατον να εναλλάξεις στατικά strings διαφορετικού μέγιστου μήκους (τα έχουμε ξαναπεί όπως θυμάσαι).

Τα στατικά strings (όπως και οι στατικοί πίνακες) έχουν fixed μέγιστο μήκος το οποίο δεν αλλάζει ότι και να κάνεις. Επίσης τα ονόματα-δείκτες των στατικών strings (όπως και των στατικών πινάκων) είναι κι αυτά fixed, που σημαίνει πως δεν μπορούν να χρησιμοποιηθούν ως LVALUES. Εν ολίγοις, είναι αδύνατον να εναλλάξεις 2 στατικά strings (ή πίνακες) διαφορετικού μέγιστου μήκους.

Εντύπωσέ το! :P

Αυτό που μπορείς να κάνεις με τα στατικά strings είναι τα ορίσεις με ίδιο μέγιστο μήκος, και να εναλλάξεις ότι περιέχουν στο τρέχον μήκος τους (το οποίο μπορεί να διαφέρει) και προφανώς πρέπει η ρουτίνα σου να λαμβάνει υπόψη της ποιο από τα 2 strings έχει το μικρότερο τρέχον μήκος, ώστε να διαχειριστείς και τους χρακτήρες που θα περισσεύουν από το άλλο string.


Δηλαδη αυτη εδω η συνάρτηση δουλευει by lack ? http://ideone.com/lZm4A
Στατικό ειναι οτιδήποτε δεν δηλώνεται με την malloc() ή την calloc() ?
Mπορω να εναλλάξω strings που έχουν εκχωρηθεί δυναμικά?

Και την τελευταια σου παράγραφο δεν την καταλαβα... πως μπορει το μήκος ενος string
εφοσον εχει ορισθει το ιδιο να διαφέρει? :S
Αν δεν κάνω λάθος

Κώδικας: Επιλογή όλων
char s1[4]=" ABC" , char s2[4] = " DEF ";


αυτά έχουν ιδιο μήκος.
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 15 Φεβ 2012, 23:32

Star_Light έγραψε:
Δηλαδη αυτη εδω η συνάρτηση δουλευει by lack ? http://ideone.com/lZm4A

Αυτά είναι strings ίδιου μέγιστου μήκους, SIZE.

έγραψε:Στατικό ειναι οτιδήποτε δεν δηλώνεται με την malloc() ή την calloc() ?

Οτιδήποτε ορίζεται με []

έγραψε:Mπορω να εναλλάξω strings που έχουν εκχωρηθεί δυναμικά?

Εννοείται, εναλλάσσεις τους δείκτες τους.

έγραψε:Και την τελευταια σου παράγραφο δεν την καταλαβα... πως μπορει το μήκος ενος string
εφοσον εχει ορισθει το ιδιο να διαφέρει? :S

Αν έχεις διαβάσει το site μου, κάνω πολύ σαφή τον διαχωρισμό μεταξύ τρέχοντος και μέγιστου μήκους (και όχι μόνο στο site μου, αλλά κι εδώ, πολλές φορές ;)

έγραψε:Αν δεν κάνω λάθος

Κώδικας: Επιλογή όλων
char s1[4]=" ABC" , char s2[4] = " DEF ";

αυτά έχουν ιδιο μήκος.

Αυτά είναι και τα 2 λάθος: στο s1 ορίζεις μέγιστο μήκος 4 χαρακτήρες και το αρχικοποιείς με 5, στο s2 ορίζεις μέγιστο μήκος 4 χαρακτήρες και το αρχικοποιείς με 6.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 15 Φεβ 2012, 23:46

Έχεις δικιο έκανα κάποια λάθη λογω κούρασης. :(

Κώδικας: Επιλογή όλων
char s1[4]="ABC" , char s2[4]="DEF";


Το μήκος ενος string δίνεται απο την strlen(s) χωρις τον '\0' για αυτο θες ενα +1. Ενω το μέγεθος δινεται απο τον τελεστή sizeof.

Aπλα εσυ εννοείς οτι άν εγω έχω ορισει 2 πίνακες χαρακτήρων έστω

Κώδικας: Επιλογή όλων
char s1[SIZE]={'\0'} , char s2[SIZE]={'\0'} με SIZE = 100


ωστε να φιλοξενεί 2 string με μέγιστο 100 τοτε ο χρηστης μπορει να δωσει τη μεν μια ενα string 5 χαρακτήρων και την δευτερη 7 ή και παραπανω... μεχρι 99
αυτο ειναι το τρέχον μήκος και το 100 ειναι το μέγιστο.
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 16 Φεβ 2012, 00:16

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

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

#define pressENTER() \
do{ \
char mYcHAr; \
printf( "press ENTER..." ); \
while ( (mYcHAr=getchar()) != '\n' && mYcHAr != EOF ) \
; \
}while(0)

/*********************************************************//**
*
************************************************************/
int s_swap( char **s1, char **s2 )
{
char *temp = NULL;

if ( !s1 || !s2 )
return 0; /* FALSE */

temp = *s1;
*s1 = *s2;
*s2 = temp;

return 1; /* TRUE */
}

/*********************************************************//**
*
************************************************************/
int s_swap_static( char *s1, char *s2, const int maxlen )
{
char *temp = NULL;
size_t size = maxlen * sizeof(char);

if ( !s1 || !s2 || maxlen < 1 || NULL == (temp=malloc(size)) )
return 0; /* FALSE */

memcpy(temp, s1, size);
memcpy(s1, s2, size);
memcpy(s2, temp, size);

free( temp );
return 1; /* TRUE */
}

/*********************************************************//**
*
************************************************************/
#define myMAX(x,y) ( (x) > (y) ? (x) : (y) )
int s_swap_static2( char *s1, char *s2 )
{
char *temp = NULL;
size_t size = 0;

if ( !s1 || !s2 )
return 0; /* FALSE */

size = myMAX(strlen(s1), strlen(s2)) * sizeof(char);
if ( NULL == (temp = malloc(size)) )
return 0; /* FALSE */

memcpy(temp, s1, size);
memcpy(s1, s2, size);
memcpy(s2, temp, size);

free( temp );
return 1; /* TRUE */
}

/*********************************************************//**
*
************************************************************/
int s_swap_static3( char *s1, char *s2 )
{
char c = '\0', *cp = NULL;
int i = 0;

if ( !s1 || !s2 )
return 0; /* FALSE */

for (i=0; s1[i] && s2[i]; i++)
{
c = s1[i];
s1[i] = s2[i];
s2[i] = c;
}

if ( '\0' != *(cp = &s1[i]) ) {
while ( s1[i] )
s2[i] = s1[i++];
*cp = '\0';
}
else if ( '\0' != *(cp = &s2[i]) ) {
while ( s2[i] )
s1[i] = s2[i++];
*cp = '\0';
}

return 1; /* TRUE */
}
/*********************************************************//**
*
************************************************************/
int main( void )
{
/* string literals */
char *s1 = "str1long";
char *s2 = "str2";
/* static strings of same max length */
char t1[ 80+1 ] = "str1long";
char t2[ 80+1 ] = "str2";

/* swap string literals */

puts("\nBEFORE s_swap():");
printf("\ts1 = %s\n\ts2 = %s\n", s1, s2 );

if ( !s_swap(&s1, &s2) )
puts("*** s_swap() failed!");

puts("AFTER:");
printf("\ts1 = %s\n\ts2 = %s\n", s1, s2 );

/* Method 1: swap static strings of same max length */

puts("\nBEFORE s_swap_static():");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

if ( !s_swap_static(t1, t2, 80+1) )
puts("*** s_swap_static() failed!");

puts("AFTER:");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

/* Method 2: swap static strings of same max length */

puts("\nBEFORE s_swap_static2():");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

if ( !s_swap_static2(t1, t2) )
puts("*** s_swap_static2() failed!");

puts("AFTER:");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

/* Method 3: swap static strings of same max length */

puts("\nBEFORE s_swap_static3():");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

if ( !s_swap_static3(t1, t2) )
puts("*** s_swap_static3() failed!");

puts("AFTER:");
printf("\tt1 = %s\n\tt2 = %s\n", t1, t2 );

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

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 16 Φεβ 2012, 01:38

Απλα δεν μπορω να καταλάβω γιατι μου είπες αυτο με τα στατικά strings.... άλλωστε μεσω της define ιδιο μήκος τα ορισα εξαρχής.

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


#include<stdio.h>
#include<string.h>
#define SIZE 15

int main()
{
char s[SIZE]={'\0'};

printf(" Give a string : ");
fgets(s , SIZE , stdin);
puts("\n");

printf(" Η συμβολοσειρά που δόθηκε ειναι η : %s " , s );
printf( " Το μέγεθος του τρέχοντος μήκους του string που δώσατε ήταν : %ld \n" , strlen(s) + 1 );
printf( " Το μέγιστο μήκος / μέγεθος της συμβολοσειράς θα πρέπει να είναι : %ld \n " , sizeof(s));

return 0;
}


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


Give a string : Nick


Η συμβολοσειρά που δόθηκε ειναι η : Nick
Το μέγεθος του τρέχοντος μήκους του string που δώσατε ήταν : 5
Το μέγιστο μήκος / μέγεθος της συμβολοσειράς θα πρέπει να είναι : 15


Μετράει και το ENTER? :S
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 16 Φεβ 2012, 10:50

Star_Light έγραψε:Απλα δεν μπορω να καταλάβω γιατι μου είπες αυτο με τα στατικά strings.... άλλωστε μεσω της define ιδιο μήκος τα ορισα εξαρχής.

Σου είπα πως είναι αδύνατον να εναλλάξεις 2 στατικά strings διαφορετικού μέγιστου μήκους.

έγραψε:
Spoiler: show
Κώδικας: Επιλογή όλων


#include<stdio.h>
#include<string.h>
#define SIZE 15

int main()
{
char s[SIZE]={'\0'};

printf(" Give a string : ");
fgets(s , SIZE , stdin);
puts("\n");

printf(" Η συμβολοσειρά που δόθηκε ειναι η : %s " , s );
printf( " Το μέγεθος του τρέχοντος μήκους του string που δώσατε ήταν : %ld \n" , strlen(s) + 1 );
printf( " Το μέγιστο μήκος / μέγεθος της συμβολοσειράς θα πρέπει να είναι : %ld \n " , sizeof(s));

return 0;
}


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


Give a string : Nick


Η συμβολοσειρά που δόθηκε ειναι η : Nick
Το μέγεθος του τρέχοντος μήκους του string που δώσατε ήταν : 5
Το μέγιστο μήκος / μέγεθος της συμβολοσειράς θα πρέπει να είναι : 15

Μετράει και το ENTER? :S

Ναι, γιατί δεν το έσβησες μετά την fgets().

Το παρακάτω δίνει σωστό αποτέλεσμα;

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

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

#define SIZE 15
#define pressENTER() \
do{ \
char mYcHAr; \
printf( "press ENTER..." ); \
while ( (mYcHAr=getchar()) != '\n' && mYcHAr != EOF ) \
; \
}while(0)

void foo( char s[SIZE] )
{
printf( "Η συμβολοσειρά που δόθηκε ειναι η: %s\n" , s );
printf( "Το μέγεθος του τρέχοντος μήκους του string που δώσατε ήταν: %lu \n",
strlen(s) + 1
);
printf( "Το μέγιστο μήκος της συμβολοσειράς θα πρέπει να είναι: %lu \n",
sizeof(s)
);

return;
}

int main( void )
{
char s[SIZE]={'\0'};

printf("Give a string : ");
fgets(s , SIZE , stdin);

foo(s);

pressENTER();
exit( EXIT_SUCCESS );
}

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

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 16 Φεβ 2012, 13:03

Προ λιγου με ενημέρωσαν οτι τσίμπησα το Lower!!!!!!!!!!!!!!!!! Παει και αυτο.

migf1 θέλω ένα σχηματικο παράδειγμα αν μπορεις με τον κωδικα που ανέβασα γιατι ναι μεν
έβαλα τον τελεστή || μεσα στην while για τα 2 strings αλλα ρε συ δεν καταλαβαινω αφου ενα απο τα 2
φτανει στον κενο χαρακτηρα πως συνεχιζεται μετα και γινεται το swap ? :/

Και για να μην σε κουράσω πάρε σαν ονοματα το μεν ενα -> Nik και το επίθετο Αποστόλου :P
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 16 Φεβ 2012, 13:07

Συγχαρητήρια για το Lower! :)

Για να μη με κουράζεις, συνέκρινε τη δική σου ρουτίνα με την s_swap_static3() από τον κώδικα που ποστάρισα χτες, που κάνει αυτό που προσπαθείς να κάνεις :) Βάλε extra printf, βάλε τες στον gdb, βάλε ότι εν πάσει περιπτώσει σε εξυπηρετεί καλύτερα για να συγκρίνεις τις 2 ρουτίνες.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

ΠροηγούμενηΕπόμενο

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