Προς το περιεχόμενο

Ερωτήσεις για C


capoelo

Προτεινόμενες αναρτήσεις

Του λέει να χρησιμοποιήσει 13 θέσεις για το τύπωμα του value (εκτός αν δεν χωράει, οπότε θα πιάσει περισσότερες). Μπορείς να του βάλεις και -13 αν θες να σου στοιχίζει το value από την άλλη μεριά κατά το τύπωμα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Μπορείς να του βάλεις και -13 αν θες να σου στοιχίζει το value από την άλλη μεριά κατά το τύπωμα.

αυτο μου το εξηγεις μια αν δεν βαριεσαι? δηλαδη το 13 ή οποιος αλλος αριθμος εκει περα,μπαινει για λογους στοιχισης?

εχεις καποιο παραδειγμα με κωδικα που να φαινεται η διαφορα?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Παρακαλώ :)

 

Απλώς να συμπληρώσω πως ειδικά για τη printf() το 13 μπορεί να είναι και μεταβλητή, αν βάλεις * αντί για νούμερo, και κατόπιν περάσεις σαν όρισμα τη μεταβλητή ακριβώς ΠΡΙΝ από το value (για την scanf νομίζω δεν γίνεται... εκεί κάνει άλλη δουλειά το * )

 

int n = -13;

printf( "%d%*d\n", element, n,value );

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτο με την printf και την εκτυπωση μέσα σε πεδια που ρωταει ο koslibpro  μπορει ακομη πιο ευκολα να το καταλαβει κάποιος χρησιμοποιώντας : |   |

 

Πχ

 
char s[STR_LEN+1] = "Learning C";

printf("|%16s|\n", s); 
printf("|%-6s|\n", s); 
 

για strings. Για ακεραιους το μονο που αλλαζει ειναι ο μορφοποιητης απο %s σε %d.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

*str = 0;
str[0] = '\0' ;
strcpy( str , "");
strcat( str , "");  
 

 

 

Η τελευταια δεν ειναι ισοδυναμη με τις υπολοιπες . Σωστα?

 

Η strcat οταν έχεις κενο string μοιάζει με την strcpy.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το παρακάτω βρισκει αν μια λέξη ειναι παλινδρομη ή οχι

 

 

 
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define STR_LEN 50
void is_palindrome( char [] , char []);
void read_line(char [] , int );
int main( void )
{
    char input[STR_LEN + 1] = {'\0'};
    char *start = input;
    
    for(; {
    
    printf("Enter a word (Enter a single letter to terminate) : \n");
    read_line(input , STR_LEN );
    
    if(strlen(input) < 2)
    break;
    
    is_palindrome( input , start);
}
        
        return 0;
}
void read_line(char str[] , int n)
{
    int ch , i=0;
    int letter[26]={0} , count=0;  
    while( (ch = getchar()) != '\n' ) {
        
        /*count = letter[ ch - 'a' ]++ ;
        
        if( count > 1)
        break;*/
        
        if(i < n )
        str[i++] = ch;
    }
        
        str[i] = '\0';
}
void is_palindrome( char *input , char *start )
{
    
    bool check=true;
    
    while( *input )
    input++;
    
    while( *start )
    if( *start++ != *--input)
    check = false;
    
    if( !check )
    printf("Word %s is not palindrom\n" , input);
    
    else
    
    printf("Word : %s is palindrom\n" , input );
    
    return;
}
 

 

 

Ο αλγοριθμος που σκεφτηκα εγω εχει ως εξής :

 

-ΔΙΑΒΑΣΕ ΜΙΑ ΛΕΞΗ

- ΦΤΑΣΕ ΣΤΟ ΤΕΛΟΣ ΤΟΥ string

- ΜΕΤΑ ΠΗΓΑΙΝΕ ΠΡΟΣ ΤΑ ΠΙΣΩ ΣΥΓΚΡΙΝΟΝΤΑΣ ΚΑΘΕ ΛΕΞΗ ΤΟΥ ΤΕΛΟΥΣ ΜΕ ΑΥΤΟ ΤΗς ΑΡΧΗΣ

- ΑΝ ΤΑ ΓΡΑΜΜΑΤΑ ΕΙΝΑΙ ΟΛΑ ΙΔΙΑ ΤΟΤΕ Η ΛΕΞΗ ΕΙΝΑΙ ΠΑΛΙΝΔΡΟΜΗ.

 

Ο κωδικας μου βγηκε αν και πως σας φαινεται οτι θελει ενα γραμμα ωστε να τερματισει? και οχι πχ ενα Q ή q που ειναι πιο αντιπροσωπευτικο... αισχρό?

 

επισης θελω να κανω skip με κάποιο τροπο τα διπλα γραμματα πχ ΑΝΝΝΑ ή ΑΑΑΑΑΑ

ωστε να βελτιωσω λιγο τα errors της εισοδου.... θελω να χρησιμοποιησω και μια συναρτηση απο την libc που

θα κανει break αν ειναι αριθμος και οχι γραμμα αυτο που δοθηκε.

 

http://www.rinkworks.com/words/palindromes.shtml

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Χμ.. θα μπορούσε να γίνει με τον ίδιο τρόπο, δίχως την χρήση δεικτών (για να "κρύψουμε" το πρώτο while/input++ - αλλά χρεωνόμαστε τα int οπότε.. μια ή άλλη τελικά) ως εξής:

 

/* Palindromic word (v2)? */

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

int main(void)
{
	char *szInput = "tattarrattat";

	int nStr = strlen(szInput),
		nEnd = nStr - 1,
		nNot = 0;

	if(nStr)
		for(nStr = 0; !nNot && nStr < nEnd; nStr++, nEnd--)
			nNot = toupper(szInput[nStr]) != toupper(szInput[nEnd]);

	puts(nNot ? "It is not :-(": "It is :-)");

	puts("\nPress Enter to exit..");
	getchar();

	return 0;
}

Υ.Γ.

Το πρόγραμμα έχει δοκιμασθεί σε C++ Builder (με ορισμένες παλινδρομικές λέξεις από εδώ) και μπορεί να περιέχει bugs ή άλλες αβλεψίες.

 

Ένα ακόμη τρικ (πολύ εύκολο σε C++ ή σε άλλες γλώσσες που προσφέρουν τέτοιες έτοιμες συναρτήσεις) για παράδειγμα είναι η άμεση αντιστροφή του string και η σύγκριση του με την είσοδο οπότε αν ταιριάζουν τότε η είσοδος πρόκειται για παλινδρομική.. (η strrev που παρέχουν ορισμένοι C μεταφραστές δεν είναι ANSI-C για να είσαι σίγουρος ότι υπάρχει παντού :-/).

 

// Palindromic?

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int main(void)
{
	string strInput("101"),
		   strTest(strInput);

	reverse(strTest.begin(), strTest.end());

	cout <<(strInput == strTest ? "It is :-)": "It is not :-(")<<endl;

	return 0;
}

 

Επεξ/σία από Directx
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Εφόσον έχεις δει ότι s[0] και s[N] είναι ίσα, δε χρειάζεται να κάνεις το ίδιο για τα s[N] και s[0]. Επίσης, αν θεωρήσουμε ότι το empty string είναι palindrome (που νομίζω ότι φανερά έτσι πρέπει να το δει κανείς) δε χρειάζεται να το κάνουμε special-case.

 

Επομένως

int is_palindrome(const char* str) {
    const char* last = str + strlen(str) - 1;
    while (str < last) {
        if (*str++ != *last--) return 0;
    }

    return 1;
}

Θεωρώ ότι η παραπάνω μορφή έχει το τεράστιο πλεονέκτημα του ότι φωνάζει από μακριά τι ακριβώς κάνει. Με το που διαβάζεις "is_palindrome" και "while (str < last)" δεν έχει μείνει τίποτα αφημένο στη φαντασία. Τα ονόματα των μεταβλητών θα μπορούσαν να είναι καλύτερα αλλά σε κάτι τόσο απλό δε νομίζω πως χρειάζεται.

 

@Star_Light: Αυτό που κάνεις με το printf μέσα στην is_palindrome είναι λάθος σκεπτικό. Αν θες να το αφήσεις έτσι (που δεν το συστήνω), ονόμασέ την print_if_string_is_palindrome().

 

@Directx: Αν πρόκειται να χρησιμοποιήσεις hungarian γιατί το κάνεις έτσι; To "szInput" είναι μια χαρά, αλλά τα "nΕnd" και "nNot" είναι τελείως φάουλ σαν ονόματα. "cchInput" και "fPalindrome" θα ήταν ίσως τα καλύτερα.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

@Directx: Αν πρόκειται να χρησιμοποιήσεις hungarian γιατί το κάνεις έτσι; To "szInput" είναι μια χαρά, αλλά τα "nΕnd" και "nNot" είναι τελείως φάουλ σαν ονόματα. "cchInput" και "fPalindrome" θα ήταν ίσως τα καλύτερα.

Απλά από συνήθεια, πάνε τώρα πάνω από 15 χρόνια που σε κάποιο βιβλίο για Windows προγραμματισμό είχα πετύχει ένα μικρό πίνακα ο οποίος χρησιμοποιούσε αυτά τα prefix (πιθανότητα και άλλα που δεν τα θυμάμαι πια ή ...εισήγαγα και κάποια δικά μου που προέκυψαν στην πορεία :-D), κοιτάζοντας από περιέργεια εδώ (μιας και το κουβεντιάζουμε)  βλέπω ότι κάποια πράγματα που θυμάμαι από τότε ακόμα χρησιμοποιούνται (..με την διαφορά ότι εγώ έχω συνηθίσει πχ. το "b = bool" και το "n = integer δίχως διάκριση count ή index" [η Wikipedia λαμβάνει υπόψη της και αυτή την εκδοχή, και την άλλη όπου "f = bool" και "i = integer/index"] - αλλά σαφέστατα δεν πρόκειται για θέσφατα τα οποία χρησιμοποιώ παντού, κάθε άλλο σέβομαι πάντα την σήμανση των άλλων project ή ακόμα και την μη σήμανση αν έτσι έχει αποφασιστεί. Επεξ/σία από Directx
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Εφόσον έχεις δει ότι s[0] και s[N] είναι ίσα, δε χρειάζεται να κάνεις το ίδιο για τα s[N] και s[0]. Επίσης, αν θεωρήσουμε ότι το empty string είναι palindrome (που νομίζω ότι φανερά έτσι πρέπει να το δει κανείς) δε χρειάζεται να το κάνουμε special-case.

 

Επομένως

int is_palindrome(const char* str) {
    const char* last = str + strlen(str) - 1;
    while (str < last) {
        if (*str++ != *last--) return 0;
    }

    return 1;
}

Θεωρώ ότι η παραπάνω μορφή έχει το τεράστιο πλεονέκτημα του ότι φωνάζει από μακριά τι ακριβώς κάνει. Με το που διαβάζεις "is_palindrome" και "while (str < last)" δεν έχει μείνει τίποτα αφημένο στη φαντασία. Τα ονόματα των μεταβλητών θα μπορούσαν να είναι καλύτερα αλλά σε κάτι τόσο απλό δε νομίζω πως χρειάζεται.

 

@Star_Light: Αυτό που κάνεις με το printf μέσα στην is_palindrome είναι λάθος σκεπτικό. Αν θες να το αφήσεις έτσι (που δεν το συστήνω), ονόμασέ την print_if_string_is_palindrome().

 

Αυτο που μου δινεις εδω δεν τρεχει ..... Αν βαλω την συναρτηση ετσι οπως ειναι στο προγραμμα θα μου βγαζει λαθος αποτελεσματα . Δοκιμασε το και εσυ να δεις. Παρολαυτα το 1ο loop που εχω εγω ειναι περιττο η δικια σου εκδοση ειναι πιο συμπτυγμενη. Ωστοσο δεν θα περασω const char * γιατι το string το περιμενω απο τον χρηστη και δεν ειναι literal. Επισης αυτο με το s[0] και s[N] που λες δεν το καταλαβαινω.... που εχω δει οτι ειναι ισα? Επισης γιατι αν η λεξη ειναι παλινδρομη να επιστρεψω 0 και οχι 1 που σαν τιμη μεσα στην if θα δουλεψει απευθειας και δεν θα χρειαστει να χρησιμοποιήσω ! μπροστα απο την κληση της συνάρτησης ωστε !0 = 1 . ΓΙα το is_palindrome δεν εχεις αδικο συνηθως τετοια ονομασια περιμενει διτιμη εκτιμηση bool κτλπ . Τελοςπαντων εγω την έχω κάνει έτσι :

 

 

 
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include <ctype.h>
#define STR_LEN 50
int is_palindrome( char []);
void read_line(char [] , int );
int main( void )
{
    char input[STR_LEN + 1] = {'\0'};
    
    for(; {
    
    printf("Enter a word (Enter a single letter to terminate) : \n");
    read_line(input , STR_LEN );
    
    if(strlen(input) < 2)
    break;
    
    if( is_palindrome( input ) )
    printf(" Word %s is palindrome " , input);
    
    else
    printf(" Word %s is not palindrome " , input);
}
        
        return 0;
}
void read_line(char str[] , int n)
{
    int ch , i=0;
    while( (ch = getchar()) != '\n' ) {
        
        if( !isalpha(ch)) {
        printf(" \n *Rejected* '%c' is not a letter " , ch);
        continue;
        }
        
        if(i < n )
        str[i++] = ch;
    }
        
        str[i] = '\0';
}
int is_palindrome(char* str) {
    
    char* last = str;
    while (*str) {
        if (*str++ != *last--) return 1;
    }
    return 0;
}
 

 

 

p.s1 Δεν μου αρεσει να αφησω το last χωρις null terminated ακομη και αν δεν το χρησιμοποιω πουθενα μεσα στην συναρτηση μπορει καποια στιγμη να θελησω να δω τα περιεχομενα του αν κανω debugging manually :P οποτε αν το περάσω μεσα σε μια puts να υπάρξει ζητημα.

 

p.s2 Έχω βαλει και εναν στοιχειωδη ελεγχο στο προγραμμα ωστε να απορριπτει συμβολα τα οποια δεν ειναι γραμματα μεσα σε μια λέξη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ρίξε μια ματιά στον κώδικα της libs: http://x-karagiannis.gr/prg/custom/doc/libs/html/s2_8c_source.html#l00255 Δοκίμασε να δεις πώς επηρεάζεται η συμπεριφορά της επιστροφής αν αφαιρέσεις το = από την επιστρεφόμενη σύγκριση.

 

EDIT:

 

Στον τελευταίο κώδικα που δίνεις, τον last τον ξεκινάς σίγουρα λάθος. Μάλλον ήθελες να γράψεις:

char *last = strlen(str)-1;

αντί για

 

char *last = str;

που γράφεις.

 

Επίσης, οι τιμές επιστροφής σου δεν μου φαίνονται σωστές. Λογικά, όταν 2 συμμετρικά γράμματα διαφέρουν...

 

if (*str++ != *last--)

πρέπει να επιστρέψεις 0, μιας και τότε η λέξη δεν είναι παλινδρομική.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Btw εχω γράψει ενα λαθος πιο πανω..... μπορεις να περάσεις και const char * εφοσον δεν τροποποιει η συναρτηση περιεχόμενα.

 

 

 

Ρίξε μια ματιά στον κώδικα της libs: http://x-karagiannis.gr/prg/custom/doc/libs/html/s2_8c_source.html#l00255 Δοκίμασε να δεις πώς επηρεάζεται η συμπεριφορά της επιστροφής αν αφαιρέσεις το = από την επιστρεφόμενη σύγκριση.

EDIT:

Στον τελευταίο κώδικα που δίνεις, τον last τον ξεκινάς σίγουρα λάθος. Μάλλον ήθελες να γράψεις:

char *last = strlen(str)-1;

αντί για
 
char *last = str;

που γράφεις.

Επίσης, οι τιμές επιστροφής σου δεν μου φαίνονται σωστές. Λογικά, όταν 2 συμμετρικά γράμματα διαφέρουν...
 
if (*str++ != *last--)

πρέπει να επιστρέψεις 0, μιας και τότε η λέξη δεν είναι παλινδρομική.

 

 

 

Nαι. Μπερδευτηκα :P

 

p.s Μην κοιταξει κανεις το προτελευταιο μου ποστ ειναι αχρηστο ολο.

 

p.s2 Δεν εχω καταλαβει ακομα παντως γιατι strlen(str) - 1 και την συγκριση δεικτων που κάνεις....

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

p.s2 Δεν εχω καταλαβει ακομα παντως γιατι strlen(str) - 1 και την συγκριση δεικτων που κάνεις....

Γιατί δεν έχει νόημα να συγκρίνεις το NUL byte με κάτι (θεωρώντας πως έχει γίνει ήδη sanity check). Η όλη λογική είναι να ξεκινάς 2 δείκτες από την αρχή και το τέλος του string και να τους μετακινείς προς το μέσο του string είτε μέχρι να συναντηθούν είτε μέχρι οι χαρακτήρες τους (που είναι συμμετρικοί) να διαφέρουν.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...