Jump to content
hitme

[help] Problema C

Recommended Posts

Salut, vreau sa citesc informatii din fisierul in.txt, sa le ordonez folosid qsort si sa le afisez in alt fisier, out,txt. Nu-mi dau seama de ce intra in bucla infinita, sau unde, ceva ajutor?


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

void verific (FILE *f)
{
if (f==NULL)
{
printf("Eroare deschidere fisier\n");
exit(1);
}
}
void afisare (char* a[], int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!=NULL)
printf("%s\n",a[i]);
}

int fqs (const void *a, const void *
{
return strcmp ( *(char**)a , *(char**)b );
}

int citesc (FILE *f, char* a[])
{
int i=0;
char buf[100];
fread(buf,sizeof(char),1,f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
}
return i;

/*
int i=0;
char buf[100];
fgets(buf,sizeof(char*),f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
fgets(buf,sizeof(char*),f);
}
return i;
*/

}

int scriu (FILE *f, char* a[], int n)
{
fwrite(a,sizeof(char*),n,f);
fputs("\n\n",f);

}


int main()
{
int n;
FILE *f=fopen("in.txt","rt");
FILE *g=fopen("out.txt","wt");
verific(f);
verific(g);
char* a[100];
n=citesc(f,a);
afisare(a,n);
scriu(g,a,n);
qsort(a,n,sizeof(char*),fqs);
scriu(g,a,n);
return 0;

}

Link to comment
Share on other sites

Salut, vreau sa citesc informatii din fisierul in.txt, sa le ordonez folosid qsort si sa le afisez in alt fisier, out,txt. Nu-mi dau seama de ce intra in bucla infinita, sau unde, ceva ajutor?


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

void verific (FILE *f)
{
if (f==NULL)
{
printf("Eroare deschidere fisier\n");
exit(1);
}
}
void afisare (char* a[], int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!=NULL)
printf("%s\n",a[i]);
}

int fqs (const void *a, const void *
{
return strcmp ( *(char**)a , *(char**)b );
}

int citesc (FILE *f, char* a[])
{
int i=0;
char buf[100];
fread(buf,sizeof(char),1,f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
}
return i;

/*
int i=0;
char buf[100];
fgets(buf,sizeof(char*),f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
fgets(buf,sizeof(char*),f);
}
return i;
*/

}

int scriu (FILE *f, char* a[], int n)
{
fwrite(a,sizeof(char*),n,f);
fputs("\n\n",f);

}


int main()
{
int n;
FILE *f=fopen("in.txt","rt");
FILE *g=fopen("out.txt","wt");
verific(f);
verific(g);
char* a[100];
n=citesc(f,a);
afisare(a,n);
scriu(g,a,n);
qsort(a,n,sizeof(char*),fqs);
scriu(g,a,n);
return 0;

}

Cateva greseli care se observa sunt operatiile de casting si derefentiere si citirea din fisier:


fread(buf,sizeof(char),1,f);

este gresit. Ar trebui sa specifici numarul de caractere care este maxim in cazul acelui buffer:


fread(buf,sizeof(char),100,f);

Secventa urmatoare este gresita:


int citesc (FILE *f, char* a[])
{
int i=0;
char buf[100];
fread(buf,sizeof(char),1,f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
}
return i;

Banuiesc ca ceea ce vrei sa faci este sa citesti din fisier in buffer iar din buffer in argumentul char** a. In acest caz nu mai ai nevoie de acel buffer:


int citesc (FILE *f, char*** a)
{
int i=0,, size = 100;
// Trebuie sa alocam memorie pentru a, care este un tablou bidimensional
// Alocam intai numarul de linii
*a = (char**)malloc(size * sizeof(char));
// Acum alocam memorie pentru fiecare coloana in parte. Presupunem ca avem 100 de caractere per linie
for(i = 0; i < size; i++)
*a[i] = (char*)malloc(size * sizeof(char));

i = 0;
while (fread(*a[i++], sizeof(char), size, f));

return i;

Desi char** a si char* a[] sunt echivalente este bine sa te hotarasti care notatie doresti sa o folosesti in cod.

In main ai uitat sa initializezi valoarea lui n.

Link to comment
Share on other sites

  • Active Members
Mersi pentru sfaturi, am facut ce mi-ai spus (desi m-am cam ametit cu pointerii), cand citesc din fisier, ce parametrii trebuie sa-i dau? nu prea inteleg de unde vine acel char*** a din functia de citire

Din cauza faptului ca in C nu exista pass-by-reference ca in C++, se mai adauga un *.

Link to comment
Share on other sites

tot bucla infinita..


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

void verific (FILE *f)
{
if (f==NULL)
{
printf("Eroare deschidere fisier\n");
exit(1);
}
}
void afisare (char* a[], int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!=NULL)
printf("%s\n",a[i]);
}

int fqs (const void *a, const void *
{
return strcmp ( *(char**)a , *(char**)b );
}

int citesc (FILE *f, char*** a)
{
int i=0;
int size=100;
*a=(char**)malloc(size * sizeof(char));
for(i=0;i<size;i++)
*a[i]=(char*)malloc(size * sizeof(char));
i=0;
while (fread(*a[i++], sizeof(char), size, f));
return i;
}

int scriu (FILE *f, char* a[], int n)
{
fwrite(a,sizeof(char*),n,f);
fputs("\n\n",f);

}


int main()
{
int n;
FILE *f=fopen("in.txt","rt");
FILE *g=fopen("out.txt","wt");
verific(f);
verific(g);
char* a[100];
n=citesc(f,a);
afisare(a,n);
scriu(g,a,n);
qsort(a,n,sizeof(char*),fqs);
scriu(g,a,n);
fclose(f);
fclose(g);
return 0;

}

Link to comment
Share on other sites

Salut, vreau sa citesc informatii din fisierul in.txt, sa le ordonez folosid qsort si sa le afisez in alt fisier, out,txt. Nu-mi dau seama de ce intra in bucla infinita, sau unde, ceva ajutor?


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

void verific (FILE *f)
{
if (f==NULL)
{
printf("Eroare deschidere fisier\n");
exit(1);
}
}
void afisare (char* a[], int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!=NULL)
printf("%s\n",a[i]);
}

int fqs (const void *a, const void *
{
return strcmp ( *(char**)a , *(char**)b );
}

int citesc (FILE *f, char* a[])
{
int i=0;
char buf[100];
fread(buf,sizeof(char),1,f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
}
return i;

/*
int i=0;
char buf[100];
fgets(buf,sizeof(char*),f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
fgets(buf,sizeof(char*),f);
}
return i;
*/

}

int scriu (FILE *f, char* a[], int n)
{
fwrite(a,sizeof(char*),n,f);
fputs("\n\n",f);

}


int main()
{
int n;
FILE *f=fopen("in.txt","rt");
FILE *g=fopen("out.txt","wt");
verific(f);
verific(g);
char* a[100];
n=citesc(f,a);
afisare(a,n);
scriu(g,a,n);
qsort(a,n,sizeof(char*),fqs);
scriu(g,a,n);
return 0;

}

Cateva greseli care se observa sunt operatiile de casting si derefentiere si citirea din fisier:


fread(buf,sizeof(char),1,f);

este gresit. Ar trebui sa specifici numarul de caractere care este maxim in cazul acelui buffer:


fread(buf,sizeof(char),100,f);

Secventa urmatoare este gresita:


int citesc (FILE *f, char* a[])
{
int i=0;
char buf[100];
fread(buf,sizeof(char),1,f);
while (*buf != '\0')
{
a[i]=strdup(buf);
if(a[i]==NULL)
{
printf("Alocare esuata");
exit(1);
}
i++;
}
return i;

Banuiesc ca ceea ce vrei sa faci este sa citesti din fisier in buffer iar din buffer in argumentul char** a. In acest caz nu mai ai nevoie de acel buffer:


int citesc (FILE *f, char*** a)
{
int i=0, siz = 100;
// Trebuie sa alocam memorie pentru a, care este un tablou bidimensional
// Alocam intai numarul de linii
if(((*a) = (char**)malloc(siz * sizeof(char))) == NULL) {
perror("eroare la alocare");
exit(1);
}
// Acum alocam memorie pentru fiecare coloana in parte. Presupunem ca avem 100 de caractere per linie
for(i = 0; i < siz; i++) {
if((*a[i] = (char*)malloc(siz * sizeof(char))) == NULL) {
perror("eroare la alocare");
exit(1);
}
}
i = 0;
while (fread(*a[i++], sizeof(char), siz, f));

return i;
}

Desi char** a si char* a[] sunt echivalente este bine sa te hotarasti care notatie doresti sa o folosesti in cod.

In main ai uitat sa initializezi valoarea lui n. Functia de comparare nu este valida. Mai jos gasesti toate modificarile:


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

void verific (FILE *f)
{
if (f==NULL)
{
printf("Eroare deschidere fisier\n");
exit(1);
}
}
void afisare (char** a, int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!=NULL)
printf("%s\n",a[i]);
}

int fqs (const void * a, const void * b ) {
const char *pointer_la_a = *(const char**)a;
const char *pointer_la_b = *(const char**)b;

return strcmp(pointer_la_a,pointer_la_;
}

int citesc (FILE *f, char*** a)
{
int i=0, siz = 100;
// Trebuie sa alocam memorie pentru a, care este un tablou bidimensional
// Alocam intai numarul de linii
if(((*a) = (char**)malloc(siz * sizeof(char))) == NULL) {
perror("eroare la alocare");
exit(1);
}
// Acum alocam memorie pentru fiecare coloana in parte. Presupunem ca avem 100 de caractere per linie
for(i = 0; i < siz; i++) {
if((*a[i] = (char*)malloc(siz * sizeof(char))) == NULL) {
perror("eroare la alocare");
exit(1);
}
}
i = 0;
while (fread(*a[i++], sizeof(char), siz, f));

return i;
}

void scriu (FILE *f, char** a, int n)
{
int i = 0;
for(i = 0; i < n; i++) {
fwrite(a[i],sizeof(char*),n,f);
fputs("\n\n",f);
}
// mai si inchidem fisierele dupa ce nu mai lucram cu aceastea
fclose(f);
}


int main()
{
int n = 100;
FILE *f=fopen("in.txt","rt");
FILE *g=fopen("out.txt","wt");
verific(f);
verific(g);
char** a;
n=citesc(f,(&a));
puts("after citesc");
afisare(a,n);
scriu(g,a,n);
qsort(a,n,sizeof(char*),fqs);
scriu(g,a,n);
return 0;

}

Edited by Ganav
Link to comment
Share on other sites

inca n-am nici o idee cum scot cuvinte din text si apoi le ordonez..


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

void verific (FILE *f)
{
if(f==NULL)
{
printf("eraore deschidere fisier");
exit(EXIT_FAILURE);
}
}

int fqs (const void *a, const void *
{
return strcmp(a,;
}

int main()
{
FILE *f=fopen("inf.txt","rt");
char a[100], cuvinte[10][25];
char *p,x[100];
int i=0,aux=0,ch,j=0;

fread(&a[0],sizeof(char),1,f);
while (a[i] != EOF)
{
i++;
fread(&a[i],sizeof(char),1,f);
}
a[i]='\0';
fseek(f,0L,0);
/*
do
{
ch=fgetc(f);
if(ch == '\n')
aux++;
} while (ch != EOF);

if(ch != '\n' && aux !=0)
aux++;
fseek(f,0L,0);
puts(a);
printf("\n%d linii \n",aux-1);
*/

p = strtok(a, " ,.-");
while(p != NULL)
{
strcpy(cuvinte+i,p);
i++;
printf("%s\n",p);
p = strtok(NULL, " ,.-");
//printf("AICI");
}
qsort(cuvinte,aux,sizeof(char),fqs);
puts(cuvinte);

fclose(f);
return 0;

}

Link to comment
Share on other sites

i-am dat de cap, cu bubble sort mai exact si fara fread,fwrite. aveti idee cum pot folosi qsort aici?


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

void verific (FILE *f)
{
if(f == NULL)
{
printf("Eroare fisier.");
exit(EXIT_FAILURE);
}
}

void afisez (char **a, int n)
{
int i;
for(i=0;i<n;i++)
puts(a[i]);
}

int fqs (const void *a, const void *
{
return strcmp(a,;
}

void sortez (char **cuvinte, int n)
{
char aux[30];
int i,gasit=0;
do
{
gasit=0;
for(i=0;i<n-1;i++)
{
if (strcmp(cuvinte[i],cuvinte[i+1]) > 0)
{
strcpy(aux,cuvinte[i]);
strcpy(cuvinte[i],cuvinte[i+1]);
strcpy(cuvinte[i+1],aux);
gasit=1;
}
}
} while (gasit);
}

void scriu (FILE *f, char **cuvinte, int n)
{
int i;
for(i=0;i<n;i++)
{
fputs(cuvinte[i],f);
fprintf(f,"\n");
}
}

int main()
{
FILE *f=fopen("inf.txt","rt");
FILE *g=fopen("inf2.txt","wt");
verific(f);
verific(g);
char c;
int i,j=0;
char **cuvinte=(char**)malloc(25*sizeof(char*));
for(i=1;i<=10;i++)
cuvinte[i]=(char*)malloc(i*sizeof(char));
while (!feof(f))
{
fscanf(f,"%c",&c);
for(i=0; ; i++)
{
if(c=='\n')
break;
cuvinte[j][i] = c;
fscanf(f,"%c",&c);
}
cuvinte[j][i] = '\0';
j++;

}

afisez(cuvinte,j);
sortez(cuvinte,j);
afisez(cuvinte,j);
scriu(g,cuvinte,j);

free(cuvinte);
for(i=1;i<=10;i++)
free(cuvinte[i]);
fclose(g);
fclose(f);
return 0;
}

unde inf.txt

zahar

paine

si

altele

sortare

Link to comment
Share on other sites

Poftim aici:


/*
* sort.c
*
* Created on: Jan 24, 2015
* Author: JIHAD
*/

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

typedef struct {
char** items;
size_t nItems;
size_t size;
size_t block_size;
} item_list;

item_list* unsorted;
item_list* temp_list;
int cmpfunc(const void *a, const void *
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}


item_list* create_list(size_t block_size) {
item_list* pList = malloc(sizeof(item_list));
if (NULL != pList) {
pList->nItems = 0;
pList->size = block_size;
pList->block_size = block_size;
pList->items = malloc(sizeof(char*)*block_size);
if (NULL == pList->items) {
free(pList);
return NULL;
}
}
return pList;
}

void delete_list(item_list* pList) {
free(pList->items);
free(pList);
}

int add_to_list(item_list* pList, char *word) {
size_t nItems = pList->nItems;
if (nItems >= pList->size) {
size_t newSize = pList->size + pList->block_size;
void* newWords = realloc(pList->items, sizeof(char*)*newSize);
if (NULL == newWords) {
return 0;
} else {
pList->size = newSize;
pList->items = (char**)newWords;
}

}

pList->items[nItems] = word;
++pList->nItems;
return 1;
}

char** list_start(item_list* pList) {
return pList->items;
}

char** list_end(item_list* pList) {
return &pList->items[pList->nItems];
}


int load_items(char *file, item_list* pList)
{
FILE *file_handle;
char nutt2[4096];
char *temp;
if((file_handle=fopen(file,"r"))==NULL) {
printf("[!] FATAL: Cannot open %s \n", file);
return -1;
} else {
while (fgets(nutt2,sizeof(nutt2),file_handle)){
temp = strdup (nutt2);
temp = strtok (temp, "\n");
add_to_list(pList, temp);
} fclose(file_handle);
printf("[!] INFO: File %s loaded.\n", file);
return 1;
}
return 0;
}

int load_unsorted_list(char *file)
{
FILE *filecheck;
if(unsorted != NULL){
delete_list(unsorted);
unsorted = create_list(2);
if(file != NULL){
if((filecheck=fopen(file,"r"))!=NULL)
load_items(file, unsorted);
else {
printf("file %s doesn't exists.\n", file);
return -1;
}
}
return 1;
} else {
unsorted = create_list(2);
if(file != NULL){
if((filecheck=fopen(file,"r"))!=NULL)
load_items(file, unsorted);
else {
printf("file %s doesn't exists.\n", file);
return -1;
}
}
return 1;
}
return 0;
}

int show_list_items(item_list* pList){
char **iterItem;
FILE* sortfile=fopen("sorted.txt","wt");
//poti implementa error checking.
if(pList != NULL)
for (iterItem = list_start(pList); iterItem != list_end(pList); ++iterItem) {
fprintf(sortfile,"%s\n", *iterItem);
printf("%s\n", *iterItem);
}
fclose(sortfile);
return 0;
}

int each_line_sorting(item_list* pList){
char **iterItem;
char *tok, *saved;
if(pList != NULL){
for (iterItem = list_start(pList); iterItem != list_end(pList); ++iterItem) {
printf("Processing: %s\n", *iterItem);
temp_list = create_list(2);
for (tok = strtok_r(*iterItem, " ", &saved); tok; tok = strtok_r(NULL, " .", &saved))
{
add_to_list(temp_list, tok);
}
qsort(temp_list->items, temp_list->nItems, sizeof(char *), cmpfunc);
show_list_items(temp_list);
delete_list(temp_list);
}
}
return 0;
}


int all_words_sorting(item_list* pList){
char **iterItem;
char *tok, *saved;
if(pList != NULL){
temp_list = create_list(2);
for (iterItem = list_start(pList); iterItem != list_end(pList); ++iterItem) {
for (tok = strtok_r(*iterItem, " ", &saved); tok; tok = strtok_r(NULL, " .", &saved))
{
add_to_list(temp_list, tok);
}

}
qsort(temp_list->items, temp_list->nItems, sizeof(char *), cmpfunc);
show_list_items(temp_list);
delete_list(temp_list);
}
return 0;
}

int main(){
if(load_unsorted_list("inf.txt")){ //parametru diferit de NULL incarca fisier, daca e NULL aloca o lista goala.

/*Folosesti in caz ca vrei sortare pentru toate cuvintele din text*/
all_words_sorting(unsorted);

/*Folosesti in caz ca vrei sortare pentru toate cuvintele pentru fiecare linie in parte*/
//each_line_sorting(unsorted);

/*dealocam lista. */
delete_list(unsorted);
}
return 0;
}



Exemplul 1 cu functia all_words_sorting:

continut inf.txt:

# cat inf.txt 
paine
apa
zahar
miere

Output:

#./sort
[!] INFO: File inf.txt loaded.
apa
miere
paine
zahar

Exemplul 2 cu functia each_line_sorting:


# cat inf.txt
am cumparat paine
ma duc la aprozar

Output:

# ./sort
[!] INFO: File inf.txt loaded.
Processing: am cumparat paine
am
cumparat
paine
Processing: ma duc la aprozar
aprozar
duc
la
ma

Exemplul 3 cu functia all_words_sorting si mai multe cuvinte per line:


# cat inf.txt
am cumparat paine
ma duc la aprozar

Output:


#./sort
[!] INFO: File inf.txt loaded.
am
aprozar
cumparat
duc
la
ma
paine

deci poti folosi codul asta si in cazul in care ai un cuvant pe linie si daca ai mai multe.

Bineinteles ca posibilitatile sunt infinite, pastrand structura asta ti-ar fi si f. usor sa implementezi o functie sa stearga duplicatele, samd, plus ca dimensiunile sunt alocate dinamic, astfel ai scapat si de dat cu presupusul, cate linii max, cate cuvinte cate etc..

Succes.

Edited by JIHAD
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...