Inizia a postare qualcosa di tuo e poi vediamo di aggiustartelo. Se il tuo problema è solo la punteggiatura posta una soluzione che funziona senza punteggiatura.
Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
// Apertura in Lettura e Scrittura + verifica errore
if( (fpin=fopen(nomeFileIn, "r")) && (fpout=fopen(nomeFileOut,"w")) == NULL){
printf("Impossibile leggere/scrivere i file [%s] - [%s]", nomeFileIn,nomeFileOut);
return EXIT_FAILURE;
}
fpin
come un booleano, che viene combinato all'espressione "è fpout
uguale a 0" tramite una AND
, però non va bene così, consideriamo il seguente scenario:fpin
fallisce, fopen
ritorna false
, quindi abbiamo if (false && (fpout...))
, anche se l'apertura di fpout
avesse successo, siccome li stai combinando con una AND
, e sapendo che uno dei parametri di quella AND
è un false
, senza neanche bisogno di valutare la prossima espressione sapremo a priori che il contenuto dell'if
non verrà eseguito.if
viene eseguito? lo si ha quando:fpin
ha successo, quindi verrà valutato in true
, e l'aperura di fpout
fallisce, perchè: fopen
imposterà la variabile fpout
a NULL
, verrà comparata con NULL
, il che risulterà in true
, ora abbiamo che tutte le condizioni date in input alla AND
sono vere, il che risulterà in un true
finale. // Apertura in Lettura e Scrittura + verifica errore
fpin = fopen(nomeFileIn, "r");
fpout = fopen(nomeFileOut, "w");
if (fpin && fpout == NULL)
{
printf("Impossibile leggere/scrivere i file [%s] - [%s]", nomeFileIn, nomeFileOut);
return EXIT_FAILURE;
}
if
è molto più comprensibile, però è sempre da riconsiderare siccome non funziona come vuoi.// Elaborazione 2 - leggo il file pulito dalla punteggiatura
while( fgets(riga, RIGALENMAX, fpout) != feof ){
i=0;
j=0;
while(isalpha(riga[i])){
parola[j]=riga[i];
i++;
j++;
}
fgets
restituisce un puntatore alla stringa letta, ovvero, un puntatore a riga
, e poi lo stai comparando a... a cosa? Lo stai comparando al puntatore della funzione feof
, qui c'è un errore di una certa importanza, nel caso non lo sapessi, anche le funzioni come le variabili hanno i loro puntatori, però, i puntatori alle variabili solitamente puntano a regioni di memoria con le caratteristiche di lettura
e scrittura
, mentre i puntatori a funzione su regioni di con le caratteristiche di lettura
ed esecuzione
, spero tu abbia capito un pochettino cosa stai facendo.fgets
ritorna NULL
quando per qualsiasi errore non riesce più a leggere il contenuto del file.feof
o ferror
, anche se nel tuo caso non ne hai bisogno dato che il valore di ritorno di fgets
è sufficiente.Aggiustare è meglio che rifare da zero e, soprattutto, aiutare è più piacevole che svolgere i compiti degli altri: per quanto tu possa aver fatto confusione, si posta il codice per far vedere che si hanno buone intenzioni In generale, si inizia da una parte semplice e poi la si complica man mano che la si vede funzionare correttamente, quindi aspetta prima di complicarti la vita con i file.Non volevo pubblicarlo più che altro perchè mi sono fermato qui ed ho fatto una confusione pazzesca ahahah, il mio intento era di salvare le parole palindrome in un secondo file.
#include <stdbool.h>
#include <stdio.h>
char lower(char x) {
return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x;
}
bool palindrome(const char *word, size_t length) {
for (size_t i = 0; i < length / 2; i++)
if (lower(word[i]) != lower(word[length - i - 1]))
return false;
return true;
}
int main() {
if (palindrome("steve", 5)) printf("steve is palindrome\n");
if (palindrome("anna", 4)) printf("anna is palindrome\n");
return 0;
}
#include <stdio.h>
const char *next(const char *s) {
while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++;
return s;
}
int main() {
const char *text = "The quick, brown, fox. Jumps 123 over the lazy dog.";
for (const char *word = text; *word;) {
const char *end = next(word);
size_t length = end - word;
if (length > 0) printf("%.*s\n", length, word);
word = end + 1;
}
return 0;
}
#include <stdbool.h>
#include <stdio.h>
char lower(char x) { return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x; }
bool palindrome(const char *word, size_t length) {
for (size_t i = 0; i < length / 2; i++)
if (lower(word[i]) != lower(word[length - i - 1]))
return false;
return true;
}
const char *next(const char *s) {
while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++;
return s;
}
int main() {
const char *text = "The quick, brown, anna. Jumps 123 over the lazy racecar.";
for (const char *word = text; *word;) {
const char *end = next(word);
size_t length = end - word;
if (length > 1 && palindrome(word, length))
printf("%.*s\n", length, word);
word = end + 1;
}
return 0;
}
#include <stdbool.h>
#include <stdio.h>
char lower(char x) { return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x; }
bool palindrome(const char *word, size_t length) {
for (size_t i = 0; i < length / 2; i++)
if (lower(word[i]) != lower(word[length - i - 1]))
return false;
return true;
}
const char *next(const char *s) {
while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++;
return s;
}
int main(int argc, const char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: ./%s <input file> <output file>\n", argv[0]);
return 1;
}
FILE *in = fopen(argv[1], "r");
FILE *out = fopen(argv[2], "w");
if (!in || !out) {
fprintf(stderr, "Error: Can't read or write on file\n");
return 1;
}
for (char buffer[512]; fgets(buffer, sizeof(buffer), in);) {
for (const char *word = buffer; *word;) {
const char *end = next(word);
size_t length = end - word;
if (length > 1 && palindrome(word, length))
fprintf(out, "%.*s\n", length, word);
word = end + 1;
}
}
fclose(in);
fclose(out);
return 0;
}
Non volevo pubblicarlo più che altro perchè mi sono fermato qui ed ho fatto una confusione pazzesca ahahah, il mio intento era di salvare le parole palindrome in un secondo file.Inizia a postare qualcosa di tuo e poi vediamo di aggiustartelo. Se il tuo problema è solo la punteggiatura posta una soluzione che funziona senza punteggiatura.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 512
#define lungMaxParola 20
#define SI 1
#define NO 0
int main(int argc, const char * argv[]) {
FILE* fp;
FILE* fp2;
char nomefile[FILENAME_MAX];
char nomefile2[FILENAME_MAX];
char temp[MAX];
char s[MAX];
int i,j;
// Richiesta nome file
puts("Inserire nome file1:");
gets(nomefile);
puts("Inserire nome file2:");
gets(nomefile2);
// Apertura lettura file1 + verifica errore
if((fp=fopen(nomefile,"r"))==NULL){
printf("Errore nella lettura di %s", nomefile);
return EXIT_FAILURE;
}
// Apertura scrittura file2 + verifica errore
if((fp=fopen(nomefile,"w"))==NULL){
printf("Errore nella lettura di %s", nomefile2);
return EXIT_FAILURE;
}
// Ciclo while affinchè fine file
while(!feof(fp)){
fscanf(fp, "%s", &s[MAX]);
palindroma(s[MAX]);
}
fclose(fp);
fclose(fp2);
return EXIT_SUCCESS;
}
// Creo la funzione
int palindroma(char s[]){
int i,palindroma;
long lung;
char temp[lungMaxParola];
char parolePalindrome[MAX];
lung=strlen(s);
palindroma=SI;
for(i=0;i<lung+1;i++)
temp[i]=tolower(s[i]);
for(i=0;i<lung/2;i++){
if(temp[i]!=temp[lung-i])
palindroma=NO;
else{
for(i=0;i<lung;i++){
parolePalindrome[i]=temp[i];
}
}
}
return palindroma;
}
Seguendo il tuo consiglio ho provato a fare a step, costruendo prima funzione e corpo insomma, ho preso un pò spunto però ho cercato di farlo da solo aiutandomi con quello che sono riuscito senza utilizzare la libreria stdbool dato che non la conosco.Aggiustare è meglio che rifare da zero e, soprattutto, aiutare è più piacevole che svolgere i compiti degli altri: per quanto tu possa aver fatto confusione, si posta il codice per far vedere che si hanno buone intenzioni In generale, si inizia da una parte semplice e poi la si complica man mano che la si vede funzionare correttamente, quindi aspetta prima di complicarti la vita con i file.
Prima fai una funzione che capisce se una parola è palindroma. Una parola non è palindroma se il primo carattere è diverso dall'ultimo carattere, se il secondo carattere è diverso dal penultimo, etc... altrimenti è palindroma. Il confronto dev'essere case insensitive.
C:#include <stdbool.h> #include <stdio.h> char lower(char x) { return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x; } bool palindrome(const char *word, size_t length) { for (size_t i = 0; i < length / 2; i++) if (lower(word[i]) != lower(word[length - i - 1])) return false; return true; } int main() { if (palindrome("steve", 5)) printf("steve is palindrome\n"); if (palindrome("anna", 4)) printf("anna is palindrome\n"); return 0; }
Poi impariamo a dividere un testo in parole: una parola è una sequenza di caratteri alfabetica. Questo è un po' più difficile.
C:#include <stdio.h> const char *next(const char *s) { while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++; return s; } int main() { const char *text = "The quick, brown, fox. Jumps 123 over the lazy dog."; for (const char *word = text; *word;) { const char *end = next(word); size_t length = end - word; if (length > 0) printf("%.*s\n", length, word); word = end + 1; } return 0; }
Combiniamo le due cose e abbiamo il nostro programma che stampa le parole palindrome in una stringa.
C:#include <stdbool.h> #include <stdio.h> char lower(char x) { return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x; } bool palindrome(const char *word, size_t length) { for (size_t i = 0; i < length / 2; i++) if (lower(word[i]) != lower(word[length - i - 1])) return false; return true; } const char *next(const char *s) { while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++; return s; } int main() { const char *text = "The quick, brown, anna. Jumps 123 over the lazy racecar."; for (const char *word = text; *word;) { const char *end = next(word); size_t length = end - word; if (length > 1 && palindrome(word, length)) printf("%.*s\n", length, word); word = end + 1; } return 0; }
Ah, ma tu volevi leggere il testo da un file e salvarlo su un altro file. Facciamolo.
C:#include <stdbool.h> #include <stdio.h> char lower(char x) { return 'A' <= x && x <= 'Z' ? x - 'A' + 'a' : x; } bool palindrome(const char *word, size_t length) { for (size_t i = 0; i < length / 2; i++) if (lower(word[i]) != lower(word[length - i - 1])) return false; return true; } const char *next(const char *s) { while (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z')) s++; return s; } int main(int argc, const char *argv[]) { if (argc != 3) { fprintf(stderr, "Usage: ./%s <input file> <output file>\n", argv[0]); return 1; } FILE *in = fopen(argv[1], "r"); FILE *out = fopen(argv[2], "w"); if (!in || !out) { fprintf(stderr, "Error: Can't read or write on file\n"); return 1; } for (char buffer[512]; fgets(buffer, sizeof(buffer), in);) { for (const char *word = buffer; *word;) { const char *end = next(word); size_t length = end - word; if (length > 1 && palindrome(word, length)) fprintf(out, "%.*s\n", length, word); word = end + 1; } } fclose(in); fclose(out); return 0; }
Fine. Penso che sia tutto abbastanza chiaro, ma se c'è qualcosa che non hai capito chiedi pure.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXLEN_PAROLA 30
#define RIGALENMAX 512
#define PAROLAMAX 30
#define SI 1
#define NO 0
int main(int argc, const char * argv[]) {
FILE* fpin;
FILE* fpout;
int i,j;
int rovesciate=0;
char nomeFileIn[FILENAME_MAX];
char nomeFileOut[FILENAME_MAX];
char riga[RIGALENMAX];
char parola[PAROLAMAX];
// Chiedo nome file
puts("Inserire nome File Input:");
gets(nomeFileIn);
puts("Inserire nome File Output:");
gets(nomeFileOut);
// Apertura in Lettura e Scrittura + verifica errore
if( (fpin=fopen(nomeFileIn, "r")) && (fpout=fopen(nomeFileOut,"w")) == NULL){
printf("Impossibile leggere/scrivere i file %s-%s", nomeFileIn,nomeFileOut);
return EXIT_FAILURE;
}
// Elaborazione
while(fgets(riga, RIGALENMAX, fpin) != NULL){
i=0;
while(riga[i]!= '\n' && riga[i]!='\0'){
while(riga[i]!='\n' && riga[i]!='\0' && !isalpha(riga[i])){
fputc(riga[i],fpout);
i++;
}
j=0;
while(isalpha(riga[i])){
parola[j]=riga[i];
i++;
j++;
}
parola[j]='\0'; // Terminiamo la stringa con '\0'
if(j>0) // Se è vero allora c'è un carattere nella parola
{
for(j=0;j<strlen(parola);j++){
parola[j]=parola[strlen(parola)-j]; // Rovescio la parola
}
fputs(parola, fpout);
rovesciate++;
}
}
}
fclose(fpin);
fclose(fpout);
return EXIT_SUCCESS;
}
int palindroma(char s[]){
int i,len,palindroma;
char appoggio[MAXLEN_PAROLA];
len=strlen(s);
palindroma=SI;
for(i=0;i<len+1;i++){
appoggio[i]=tolower(s[i]);
for(i=0;i<len/2 && palindroma;i++){
if(appoggio[i]!=appoggio[len-i-1])
palindroma=NO;
}
}
return palindroma;
}
Quell'header è equivalente al tuo SI e NO, solo che è standard e usa _Bool (un intero che contiene almeno 0 e 1) al posto di int. Se vuoi capire come funziona puoi tranquillamente guardare il codice sorgente, sostanzialmente sono tre righe:senza utilizzare la libreria stdbool dato che non la conosco
#define bool _Bool
#define true 1
#define false 0
Sei sicuro che quello sia proprio l'unico problema? Proviamo a fare step by step. Il mio primo step controllava se steve e anna sono palindrome. Funzionerà?Seguendo il tuo consiglio ho provato a fare a step... l'unico problema è che eseguendo il programma, il file in output esce vuoto.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXLEN_PAROLA 30
#define RIGALENMAX 512
#define PAROLAMAX 30
#define SI 1
#define NO 0
int palindroma(char s[]){
int i,len,palindroma;
char appoggio[MAXLEN_PAROLA];
len=strlen(s);
palindroma=SI;
for(i=0;i<len+1;i++){
appoggio[i]=tolower(s[i]);
for(i=0;i<len/2 && palindroma;i++){
if(appoggio[i]!=appoggio[len-i-1])
palindroma=NO;
}
}
return palindroma;
}
int main() {
if (palindroma("steve") == SI) {
printf("steve is palindrome\n");
} else {
printf("steve is not palindrome\n");
}
return 0;
}
Ciao Steve, ho provato a rifare il codice in questa maniera:Quell'header è equivalente al tuo SI e NO, solo che è standard e usa _Bool (un intero che contiene almeno 0 e 1) al posto di int. Se vuoi capire come funziona puoi tranquillamente guardare il codice sorgente, sostanzialmente sono tre righe:
Puoi fare a meno di usarla, ma è di una banalità disarmante e rende il codice più esplicito rispetto ad usare gli int quando vuoi un valore di verità.C:#define bool _Bool #define true 1 #define false 0
Sei sicuro che quello sia proprio l'unico problema? Proviamo a fare step by step. Il mio primo step controllava se steve e anna sono palindrome. Funzionerà?
C:#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define MAXLEN_PAROLA 30 #define RIGALENMAX 512 #define PAROLAMAX 30 #define SI 1 #define NO 0 int palindroma(char s[]){ int i,len,palindroma; char appoggio[MAXLEN_PAROLA]; len=strlen(s); palindroma=SI; for(i=0;i<len+1;i++){ appoggio[i]=tolower(s[i]); for(i=0;i<len/2 && palindroma;i++){ if(appoggio[i]!=appoggio[len-i-1]) palindroma=NO; } } return palindroma; } int main() { if (palindroma("steve") == SI) { printf("steve is palindrome\n"); } else { printf("steve is not palindrome\n"); } return 0; }
Loop infinito. Inizia a sistemare il primo step e poi pensiamo ai successivi.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define RIGALENMAX 512+1
#define PAROLAMAX 30
#define SI 1
#define NO 0
// Funzione palindroma
int palindroma(char s[]){
int i,palindroma;
unsigned long len;
char appoggio[PAROLAMAX];
len=strlen(s);
palindroma=SI;
for(i=0;i<len+1;i++)
appoggio[i]=tolower(s[i]);
for(i=0;i<len/2 && palindroma;i++)
if(appoggio[i]!=appoggio[len-i-1])
palindroma=NO;
return palindroma;
}
int main() {
FILE* fpin;
FILE* fpout;
int i,j;
int palin=1;
char nomeFileIn[FILENAME_MAX];
char nomeFileOut[FILENAME_MAX];
char riga[RIGALENMAX];
char parola[PAROLAMAX];
// Chiedo nome file
puts("Inserire nome File Input:");
gets(nomeFileIn);
puts("Inserire nome File Output:");
gets(nomeFileOut);
// Apertura in Lettura e Scrittura + verifica errore
if( (fpin=fopen(nomeFileIn, "r")) && (fpout=fopen(nomeFileOut,"w")) == NULL){
printf("Impossibile leggere/scrivere i file [%s] - [%s]", nomeFileIn,nomeFileOut);
return EXIT_FAILURE;
}
// Elaborazione 1 - pulisco il file dalla punteggiatura
while (fgets(riga, RIGALENMAX, fpin) != NULL){
i=0;
while(riga[i]!='\n' && riga[i]!='\0'){
if(ispunct(riga[i]))
riga[i]=' ';
i++;
}
fputs(riga, fpout);
}
// Chiusura dei file
fclose(fpin);
fclose(fpout);
/*__________________________________________________________*/
// Riapertura del file output in lettura + verifica errore
if( (fpout=fopen(nomeFileOut,"r")) == NULL){
printf("Impossibile leggere il file [%s]", nomeFileOut);
return EXIT_FAILURE;
}
// Elaborazione 2 - leggo il file pulito dalla punteggiatura
while( fgets(riga, RIGALENMAX, fpout) != feof ){
i=0;
j=0;
while(isalpha(riga[i])){
parola[j]=riga[i];
i++;
j++;
}
if(j>=3){
if( palindroma(parola) ){
printf("[%d].%s\n", palin,parola);
palin++;
}
}
}