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

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

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

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

Δημοσίευσηαπό migf1 » 02 Ιουν 2012, 14:31

g1wrg0s έγραψε:Εχεις δικιο φιλε. Αν αυτο ζητα το παιδι που εγραψε την αρχικη απορια τοτε μια λυση ειναι αυτη. Δηλαδη να χρησιμοποιησει αυτες τις δυο συναρτησεις.
Spoiler: show
Κώδικας: Επιλογή όλων
#include "stdio.h"
#include "stdlib.h"
main()
{
int i=0;
FILE *o_f;
o_f=fopen("text","wb");
char s[]="Gia na doume ti kanei h frite()";
fwrite(s,1,sizeof(s),o_f);
fseek(o_f,7,SEEK_SET);
fwrite("DOUME",1,sizeof("DOUME")-1,o_f);
fclose(o_f);

FILE *i_f;
i_f=fopen("text","rb");
char s2[40];

fread(s2,1,40*sizeof(char),i_f);
for(i=0;i<40;i++) printf("%c",s2[i]);
fprintf("\n");
fclose(i_f);
}

Ειναι αρκετα ακαταστατος ο κωδικας και γι αυτο οποιος δεν τον καταλαβαινει ας ρωτησει. Νομιζω πως το νοημα το πιανεις .

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

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

Δημοσίευσηαπό c7p » 02 Ιουν 2012, 15:35

migf1 έγραψε:
c7p έγραψε:Έχω ένα δυαδικό αρχείο και κάνω καταγραφές σε αυτό (η κάθε καταγραφή έχει 2 "πεδία" 8 byte η κάθε μια), η κάθε καταγραφή πιάνει 16 byte. Έστω ότι έχω n, καταγραφές και θέλω να αντικαταστήσω την m καταγραφή (m<n) από την τελευταία, και μετά να διαγράψω ότι υπάρχει στη θέση τις παλιάς καταγραφής (τα τελευταία 16 bytes του αρχείου δηλαδή). Από όσο έχω δει δεν υπάρχει εντολή "διαγραφής" μέρους του αρχείου.

Ένας τρόπος είναι να δημιουργήσω ένα προσωρινό αρχείο και να κάνω αυτό που θέλω, αλλά αυτός ο τρόπος θέλει γράψιμο. Αν δεν κάνω λάθος αυτό κάνει και το ΛΣ όταν πειράζουμε γενικά αρχεία κειμένου (κρατάει ένα κρυφό προσωρινό αρχείο)

Τώρα είναι η ερώτηση, πολύ απλά θα μπορούσε να γίνει αν θα μπορούσα να να κάνω αντιγραφή της τελευταία καταγραφή στην θέση της m -εύκολο και δυνατό-, και μετά να έκανα κάπως να πείραζα την SEEK_END ώστε να δείχνει 16 byte πιο κάτω (???), πράγμα που θα ήταν αρκετά ωραίο αν γινόταν αλλά δεν ξέρω αν είναι δυνατό.

Δοκίμασες να κάνεις απευθείας update το αρχείο σου χρησιμοποιώντας τις fseek() και fwrite() ;

Εφόσον το αρχείο σου αποτελείται αυστηρά από συνεχόμενα τμήματα των 16 bytes η παραπάνω διαδικασία λογικά θα σου λειτουργήσει. Προφανώς θα πρέπει να υπολογίσεις το offset που θα περάσεις στην fseek(). Αν το αρχείο σου είναι πολύ μεγάλο, δοκίμασε με την lseek()


Το θέμα είναι ότι ήθελα να μετακινήσω το τέλος του αρχείου στην ουσία -16 byte ώστε να διαγραφή η τελευταία καταγραφή ιδίου μεγέθους.
Η λύση τελικά είναι η χρήση της ftruncate, τουλάχιστον σε Unixοειδή

http://linux.about.com/library/cmd/blcmdl2_ftruncate.htm
Άβαταρ μέλους
c7p
powerTUX
powerTUX
 
Δημοσιεύσεις: 1849
Εγγραφή: 30 Μάιος 2009, 16:09
Τοποθεσία: Κατερίνη
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 02 Ιουν 2012, 15:49

c7p έγραψε:
Το θέμα είναι ότι ήθελα να μετακινήσω το τέλος του αρχείου στην ουσία -16 byte ώστε να διαγραφή η τελευταία καταγραφή ιδίου μεγέθους.
Η λύση τελικά είναι η χρήση της ftruncate, τουλάχιστον σε Unixοειδή

http://linux.about.com/library/cmd/blcmdl2_ftruncate.htm

Πάντως δεν είναι δύσκολο να το κάνεις με χρήση προσωρινού αρχείου, για να είναι portable ο κώδικάς σου (με αντίτιμο πως η συγκεκριμένη διαδιακασία θα εκτελείται πιο αργά). Αντί για (f)truncate(...) κάνεις fread() το πλήθος των bytes που θέλεις και μετά το κάνεις fwrite() σε ένα προσωρινό αρχείο. Κατόπιν σβήνεις το αρχικό αρχείο με remove() και μετονομάζεις με rename() το προσωρινό.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό c7p » 02 Ιουν 2012, 17:10

Οκ, το ανέφερα και στην αρχική δημοσίευση πως ήξερα για το πως γίνεται με προσωρινό αρχείο απλώς ήθελα να ξέρω αν υπάρχει εναλλακτική για τη συγκεκριμένη περίπτωση.
Άβαταρ μέλους
c7p
powerTUX
powerTUX
 
Δημοσιεύσεις: 1849
Εγγραφή: 30 Μάιος 2009, 16:09
Τοποθεσία: Κατερίνη
Εκτύπωση

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

Δημοσίευσηαπό pc_magas » 03 Ιουν 2012, 20:08

Παιδιά για μια εργασία έχω κάνει τα εξής αρχεία:
Test1.c Περιέχει την main:
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include "pipe.h"

/*
This code multiplicates 2 2d arrays using multiple processes simulating a distubuted way of array multiplication by using pipes
*/


int main(int argc,char **argv)
{
int ***data;//Here we store the data

int i,j,k,status;//i,j,k variables usefull for loops
//status we need in order to check the if each child has exit with error or not

/*
*row stores the matrix fo the current row
**col trores the current column ans the answer that child sends to the father and
**result the final matrix.
*/
int *row,**col,**result,*ans,*temp;

/*
here we store the dimentions of each table that takes place into multiplication.
data1_d: stores the first matrix dimantions
data2_d: Stores the second matrix dimantions
datae_d: Stores Data for final Matrix
*/
dimensions data1_d,data2_d,data3_d;

pipe_s *p;//Here we set up the pipes and we store the pids for

pid_t pid;

const char *path = "matrix.txt";//The path we load the file

data = (int ***)load(path,&data1_d,&data2_d);//reading matrices

result=(int **)piliko(data1_d,data2_d,&data3_d);//allocating final result table

p=calloc(data1_d.height,sizeof(pipe_s));//allocating secial struct for pipes anf storing the pid of fork

if(result==NULL && p==NULL && data==NULL)//cannot allocate space for result
{
fprintf(stderr,"Cannot alocate final result table\n");
exit(EXIT_FAILURE);
}



for(i=0;i<data1_d.height;i++)//MAking Child processes
{

if(pipe(p[i].from_father)<0 && pipe(p[i].from_child)<0 )
{
fprintf(stderr,"Error with pipes.\n");
exit(EXIT_FAILURE);
}

p[i].pid=fork();

if(p[i].pid>0)//Father
{
/*Sending Line*/
if(write(p[i].from_father[1],data[0][i],data1_d.length*sizeof(int))!=(data1_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot write data\n");
exit(EXIT_FAILURE);
}

/*Sending Columns*/
for(j=0;j<data2_d.length;j++)
{
temp=column((int **)data[1],j,data2_d.height);
if(temp==NULL)
{
exit(EXIT_FAILURE);
}

printf("Send into pipe column %d\n",j);

if(
write(p[i].from_father[1],(void *)temp,data2_d.height*sizeof(int))!=data2_d.height*sizeof(int)
)
{
fprintf(stderr,"Cannot send columns\n");//error
exit(EXIT_FAILURE);
}
else
{
printf("%d has Sent \n",i);
}

free(temp);

}

}
else if(p[i].pid==0)
{
fflush(stdout);

/*Alocating Spaces*/
row=calloc(data1_d.length,sizeof(int));//for rows
ans=calloc(data3_d.length,sizeof(int));//for answer
col=calloc(data2_d.length,sizeof(int *));//for columns

/*If cannot alocate at least on of them*/
if(row==NULL && col==NULL && ans==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}

/*Allocate space for receiving column matrix*/
for(j=0;j<data2_d.length;j++)
{
col[j]=calloc(data2_d.height,sizeof(int));
if(col[j]==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}
}

/*Reading a line if not then it shows the apropriate message and exits*/
if(read(p[i].from_father[0],row,data1_d.length*sizeof(int))<=0)
{
fprintf(stderr,"No data read\n");
exit(EXIT_FAILURE);
}

/*Reading Columns*/
for(j=0;j<data2_d.length;j++)
{
if(read(p[i].from_father[0],(void *)col[j],data2_d.height*sizeof(int))<data2_d.height*sizeof(int))
{
fprintf(stderr,"No data read i=%d j=%d\n",i,j);
exit(EXIT_FAILURE);
}

}

/*Calculating row*/
for(k=0;k<data3_d.length;k++)
{
ans[i]=iMatxmult(row,col[k],data1_d.length,NULL);
}


/*Sending final result*/
if(write(p[i].from_child[1],ans,data3_d.length*sizeof(int))<(data3_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot send final result\nBye\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
else if(p[i].pid<0)
{
fprintf(stderr,"Fork failed");
exit(EXIT_FAILURE);
}
}

k=0;
while(k<data1_d.height)
{
pid=wait(NULL);

for(j=0;j<data3_d.height;j++)
{
if(pid==p[j].pid)
{
/*Reading result*/
if(read(p[j].from_child[0],result[j],data3_d.length*sizeof(int))<=0)
{
fprintf(stderr,"Cannot fetch final table\n");
exit(EXIT_FAILURE);
}
else
{
printf("Child sucessfully read data\n");
}
k++;
pid=0;
}
}
}

/*Printing results*/
puts("Printing Final result\n");
printIntMatrix(result,data3_d.height,data3_d.length);
return 0;
}


pipe.h: περιέχει μια χρήσιμη δομή για το test1.c
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef PIPEH
#define PIPEH
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include"MaxMul.h"
#include"header.h"
/*With this struct I bring all together the pids and the pipes*/
typedef struct
{
pid_t pid;//PID using for fork() function
int from_father[2];//Pipe that father sends data to child from father[0]X is the data and from father[1][X] is control
int **from_father_col;//pipe that I use to send columns
int from_child[2];//Pipe that sends the child to the father
}pipe_s;


#endif


MaxMul.h : Έχει χρήσιμες συναρτήσεις για να υπολογίζει τον τελικό πίνακα του γινομένου και να τυπώνει έναν δισδιάστατο πίνακα
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef MAXMUL_
#define MAXMUL_
#include<stdlib.h>
#include<stdio.h>

typedef struct{
unsigned int height;//Pli8os grammwn
unsigned int length;//Pli8os Stilwn
}dimensions;

/*Epistrefei enan pinaka me tis times tis col stilit tou pinaka matrix*/
int * column(int **matrix,int col,int height);

/*Ektelei ton pollaplasiasmo tis row grammis kai tis col stilis*/
int iMatxmult(int row[], int col[],unsigned int size,int * result);

/*Kataskeuazei ton teliko pinaka kai epistrefei to mege8ow tou telikou pinaka elegxontas an ginetaqi o pollaplasiasmos twn pinakwn*/
int **piliko(dimensions a,dimensions b,dimensions *result);

/*Typwnei enan height*length disdiastato pinaka*/
void printIntMatrix(int **matrix,int height,int length);
#endif


MaxMul.c Οι υλοποίηση των συναρτήσεων του MaxMul.h
Spoiler: show
Κώδικας: Επιλογή όλων
#include "MaxMul.h"
int * column(int **matrix,int col, int height)
{
int *colymn=calloc(height,sizeof(int)),i;

if(colymn!=NULL)
{
for(i=0;i<height&&matrix[i]!=NULL;i++)
{

colymn[i]=matrix[i][col];
}
}
return colymn;
}

int iMatxmult(int row[], int col[],unsigned int size,int * result)
{
int i;
int mult=0;
if(row!=NULL && col!=NULL)
{
for(i=0;(unsigned)i<size;i++)
{
mult+=row[i]*col[i];
}
return mult;
}
}

int **piliko(dimensions a,dimensions b,dimensions *result)
{
int **res,i;
if(a.length!=b.height)
{
return NULL;
}
result->height=a.height;
result->length=b.length;
res=calloc(result->height,sizeof(int *));
for(i=0;(unsigned)i<result->height;i++)
{
res[i]=calloc(result->length,sizeof(int));
}
return res;
}

void printIntMatrix(int **matrix,int length,int height)
{
int i,j;
for(i=0;i<length;i++)
{
for(j=0; j<height ; j++)
{
printf("%d\t",matrix[i][j]);
}
putchar('\n');
}
}


header.h Το Header με την δήλωση της συνάρτησης όπου χρησιμοποιεί το newload.c
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef HEADER
#define HEADER
#include<stdlib.h>
#include<stdio.h>
#include "MaxMul.h"

int ***load(const char *path,dimensions *data1_d,dimensions *data2_d);
#endif


newload.c Φορτώνει 2 δισδιάστατους πίνακες από το αρχείο
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#include "MaxMul.h"

int ***load(const char *s,dimensions *data1_d,dimensions *data2_d){

FILE *fp = fopen(s,"r");/*Oppening a file*/

/*i,j variavble for traversing 2d array*/
int i,j;

/*
A= we neeed it to make a matrix of 2d arrays
buffer = temporary storage buffer of 2d arrays
*/

int ***A=NULL,**buffer=NULL;

fscanf(fp,"%d %d",&data1_d->height,&data1_d->length); //reading Dimentions from file

A=(int ***)malloc(2*sizeof(int **)); //Allocating 2 2d arrays

buffer = (int**)malloc(sizeof(int*)*data1_d->height); //Allocating temporary storage

if(A!=NULL)
{
A[0] = (int**)malloc(sizeof(int*)*data1_d->height);//Allocating first array
}

if(A[0]==NULL)
{
return NULL;
}

/*More allocation of the array*/
for(i=0;i<data1_d->height && A[0] !=NULL ;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data1_d->length);
A[0][i] = (int*)malloc(sizeof(int)*data1_d->length);

if(buffer[i]==NULL && A[0][i]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}
}

/*Filling the 2d array with data from the file*/
for(i=0;i<data1_d->height;i++)
{

for(j=0;j<data1_d->length;j++)
{
fscanf(fp,"%d",&buffer[i][j]);
A[0][i][j] = buffer[i][j];
}
}

free(buffer); //free buffer

fscanf(fp,"%d %d",&data2_d->height,&data2_d->length); //reading dimention for the second array



buffer = (int**)malloc(sizeof(int*)*data2_d->height); //reallocating buffer

A[1] = (int**)malloc(sizeof(int*)*data2_d->height);//Allocating the second matrix

if(buffer==NULL && A[1]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}

for(i=0;i<data2_d->height;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
A[1][i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
}

/*Filling second matrix*/
for(i=0;i<data2_d->height;i++)
{

for(j=0;j<data2_d->length;j++)
{

fscanf(fp,"%d",&buffer[i][j]);
A[1][i][j] = buffer[i][j];
}
}


/*Prepating for end*/
free(buffer);
fclose(fp);


return A;//return final Matrix



}


Τα δεδομένα τα παίρνει από το αρχείο:

Spoiler: show
Κώδικας: Επιλογή όλων
2 3
11 2 3
4 5 6
3 2
7 -12
-9 1
2 3


Αυτό όπου κάνει εν ολίγοις το πρόγραμμα είναι να παίρνει 2 πίνακες και να τους Πολλαπλασιάζει με κατανεμημένο τρόπο χρησιμοποιώντας διεργασίες παιδιά και pipes. Κάθε διεργασία παιδί υπολογίζει μια γραμμή του τελικού πίνακα του γινομένου.Αλλά το πρόβλημα είναι ότι το τελικό αποτέλεσμα είναι σωστό και τα παιδιά υπολογίζουν σωστά την εκάστοτε γραμμή αλλά η διεργασία πατέρας δεν παίρνει τα σωστά δεδομένα.... Γιατί?
ΔΕΝ ΑΝΤΕΧΩ ΑΛΛΟ :cry: :cry: :cry:
Τελευταία επεξεργασία από pc_magas και 03 Ιουν 2012, 20:15, έχει επεξεργασθεί 1 φορά/ες συνολικά
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

Δημοσίευσηαπό simosx » 03 Ιουν 2012, 20:15

Off topic:
διεργασία παιδί = θυγατρική διεργασία
προσωπικό ιστολόγιο ϗ πλανήτης Ubuntu-gr
Συμβάλετε και εσείς στο ελληνικό βιβλίο Ubuntu!
1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 13.10 saucy 3.11.0-031100rc1-generic 64bit (el_GR.UTF-8, Unity ubuntu)
3 AMD E-450 APU with Radeon HD Graphics ‖ RAM 3555 MiB ‖ Sony Corporation VAIO
4 AMD nee ATI Wrestler [Radeon HD 6320] [1002:9806] {fglrx_pci}
5 eth0: Atheros Inc. AR8151 v2.0 Gigabit Ethernet [1969:1083] (rev c0) ⋮ wlan0: Atheros Inc. AR9285 [168c:002b] (rev 01)
Φτιάξτε και εσείς τη δική σας υπογραφή (παραπάνω κείμενο) αυτόματα με κλικ εδώ!
simosx
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 10334
Εγγραφή: 11 Μάιος 2008, 18:52
Launchpad: simosx
IRC: simosx
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 04 Ιουν 2012, 15:13

Εγώ τελικά έχω φτάσει στη σελίδα 522 αλλα έχω κολλήσει στο προγραμμα. Ξέρει κανείς γιατί χρησιμοποιει στην printf .2X για να τυπώσει τα Bytes; Επίσης μπορεί κάθε τιμή ενός Byte να αναπαραστηθει με 2 hex ψηφια;
1Γνώσεις→Linux: Αρχάριος┃Προγραμματισμός:Αρχάριος┃Αγγλικά:Μέτριος
2Λειτουργικό→Arch Linxu 32bit
3Προδιαγραφές→2x AMD AthlonX2 DualCore QL-66 ‖ RAM 1751 MiB ‖ Hewlett-Packard 308C - Hewlett-Packard Compaq 615
4Κάρτες γραφικών:ATI RS780M/RS780MN [Radeon HD 3200 Graphics][1002:9612]
5Δίκτυα:eth0:Marvell 88E8042 PCI-E Fast Ethernet Controller [11ab:4357] (rev 10)⋮eth1: Broadcom BCM4312 802.11b/g LP-PHY [14e4:4315](rev 01)
Πρωσοπική Ιστοσελίδα: http://giwrg98.co.cc
Άβαταρ μέλους
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 15 Ιουν 2012, 15:47

Έφτιαξα το πρώτο μου επίσημο project σε C! https://github.com/giwrg98/Comic-Organiser.git
Επίσης τώρα προσπαθώ να φτιάξω ένα πρόγραμμα όπου κάποιος θα μπορεί να έχει κάτι σαν τράπεζα και να φτιάχνει λογιαριασμούς κλπ. Αλλά για κάποιο λόγο μου βγάζει seg fault.
trapeza.h:
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef TRAPEZA_H

#define TRAPEZA_H

#define MAXNAME (120 + 1)
#define COMPARE_STR(STR1, STR2) (strcmp(lowercase_str(STR1), lowercase_str(STR2)))

int initialize(void);
int add_person(char *name, char *surname);
int print_person(char *query);
int give_money(int money);
int sub_money(int money);
char *lowercase_str(char *str);

typedef struct person {
char name[MAXNAME];
char surname[MAXNAME];
int money;
}Person;

#endif

trapeza.c:
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "trapeza.h"

Person *array;
FILE *fp;
unsigned int person_count;

int add_person(char *name, char *surname) {
Person new_person;
fp = fopen("in.dat", "a+b");
strcpy(new_person.name, name);
strcpy(new_person.surname, surname);
new_person.money = 0;
fwrite(&new_person, sizeof(new_person), 1, fp);
rewind(fp);
fread(&person_count, sizeof(unsigned int), 1, fp);
person_count++;
rewind(fp);
fwrite(&person_count, sizeof(unsigned int), 1, fp);
array = (Person *) realloc(array, sizeof(array) + sizeof(new_person));
array[person_count - 1] = new_person;
fclose(fp);
return 0;
}

int initialize(void) {
fp = fopen("in.dat", "wb+");
person_count = 0;
fwrite(&person_count, sizeof(unsigned int), 1, fp);
fclose(fp);
return 0;
}

char *lowercase_str(char *str)
{
int i;
for(i = 0; str[i]; i++) {
str[i] = tolower(str[i]);
}
return str;
}

int search_person(char *query) {
int i;
for(i = 0; i < person_count; i++) {
if((COMPARE_STR(array[i].name, query) == 0) || (COMPARE_STR(array[i].surname, query) == 0))
return 1;
}
return 0;
}

int main(void) {
initialize();
add_person("Name", "Surname");
if(search_person("Surname")) {
printf("Success!\n");
}
return 0;
}

το σφάλμα είναι στη γραμμή 42 στη lowercase_str αν και την έχω ελέγξει και στο άλλο project :/
1Γνώσεις→Linux: Αρχάριος┃Προγραμματισμός:Αρχάριος┃Αγγλικά:Μέτριος
2Λειτουργικό→Arch Linxu 32bit
3Προδιαγραφές→2x AMD AthlonX2 DualCore QL-66 ‖ RAM 1751 MiB ‖ Hewlett-Packard 308C - Hewlett-Packard Compaq 615
4Κάρτες γραφικών:ATI RS780M/RS780MN [Radeon HD 3200 Graphics][1002:9612]
5Δίκτυα:eth0:Marvell 88E8042 PCI-E Fast Ethernet Controller [11ab:4357] (rev 10)⋮eth1: Broadcom BCM4312 802.11b/g LP-PHY [14e4:4315](rev 01)
Πρωσοπική Ιστοσελίδα: http://giwrg98.co.cc
Άβαταρ μέλους
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό g1wrg0s » 15 Ιουν 2012, 16:23

Για το πρωτο project : Καλο θα ηταν να εξαφανισεις τα magic constants.
Επισης στη main γινεται να μου εξηγησεις τις πρωτες γραμμες ; Εχει τα παρακατω τα οποια δεν τα καταλαβαινω...
PRINT_MAIN_MENU;
CLEAR_STDIN;

Για το δευτερο... Προφανως αν οντως το σφαλμα βρισκεται εκει που λες τοτε εχω την εντυπωση οτι ο ελεγχος που κανεις στο for loop δεν δουλευει οπως θες . Θα προτεινα αυτο το str[i] να το αλλαζες με κατι αλλο και να τσεκαρεις αν τρως τα ιδια σφαλματα.

Βασικα τωρα που το σκεφτομαι αν ο πινακας δεν εχει κανενα μηδενικο τοτε ποτε θα τερματιστει το loop; Η απαντηση εχω την εντυπωση οτι ειναι οταν θα πεταξει segmetation, δηλαδη οταν θα πας να διαβασεις απο μνημη που δεν εχεις το δικαιωμα προσβασης.
βαλε σαν ελεγχο size[i] && i!=size_of_array
Spoiler: show
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Πρώτα βήματα ┃ Αγγλικών: Πρώτα βήματα
2 Ubuntu 12.10 quantal 3.10.20-031020-generic 32bit (el_GR.UTF-8, Unity ubuntu), Windows 8
3 Intel Core i5-3230M CPU @ 2.60GHz ‖ RAM 7923 MiB ‖ Acer VA50_HC_CR - Acer Aspire V3-571G
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915} ⋮ nVidia Device [10de:0fe1] {}
5 eth0: Broadcom NetLink BCM57785 Gigabit Ethernet PCIe [14e4:16b5] (rev 10) ⋮ wlan0: Atheros Inc. AR9462 Wireless Network Adapter [168c:0034] (rev 01)
g1wrg0s
punkTUX
punkTUX
 
Δημοσιεύσεις: 196
Εγγραφή: 26 Μάιος 2012, 10:29
Εκτύπωση

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

Δημοσίευσηαπό parenthesis » 15 Ιουν 2012, 19:11

pc_magas έγραψε:Παιδιά για μια εργασία έχω κάνει τα εξής αρχεία:
Test1.c Περιέχει την main:
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include "pipe.h"

/*
This code multiplicates 2 2d arrays using multiple processes simulating a distubuted way of array multiplication by using pipes
*/


int main(int argc,char **argv)
{
int ***data;//Here we store the data

int i,j,k,status;//i,j,k variables usefull for loops
//status we need in order to check the if each child has exit with error or not

/*
*row stores the matrix fo the current row
**col trores the current column ans the answer that child sends to the father and
**result the final matrix.
*/
int *row,**col,**result,*ans,*temp;

/*
here we store the dimentions of each table that takes place into multiplication.
data1_d: stores the first matrix dimantions
data2_d: Stores the second matrix dimantions
datae_d: Stores Data for final Matrix
*/
dimensions data1_d,data2_d,data3_d;

pipe_s *p;//Here we set up the pipes and we store the pids for

pid_t pid;

const char *path = "matrix.txt";//The path we load the file

data = (int ***)load(path,&data1_d,&data2_d);//reading matrices

result=(int **)piliko(data1_d,data2_d,&data3_d);//allocating final result table

p=calloc(data1_d.height,sizeof(pipe_s));//allocating secial struct for pipes anf storing the pid of fork

if(result==NULL && p==NULL && data==NULL)//cannot allocate space for result
{
fprintf(stderr,"Cannot alocate final result table\n");
exit(EXIT_FAILURE);
}



for(i=0;i<data1_d.height;i++)//MAking Child processes
{

if(pipe(p[i].from_father)<0 && pipe(p[i].from_child)<0 )
{
fprintf(stderr,"Error with pipes.\n");
exit(EXIT_FAILURE);
}

p[i].pid=fork();

if(p[i].pid>0)//Father
{
/*Sending Line*/
if(write(p[i].from_father[1],data[0][i],data1_d.length*sizeof(int))!=(data1_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot write data\n");
exit(EXIT_FAILURE);
}

/*Sending Columns*/
for(j=0;j<data2_d.length;j++)
{
temp=column((int **)data[1],j,data2_d.height);
if(temp==NULL)
{
exit(EXIT_FAILURE);
}

printf("Send into pipe column %d\n",j);

if(
write(p[i].from_father[1],(void *)temp,data2_d.height*sizeof(int))!=data2_d.height*sizeof(int)
)
{
fprintf(stderr,"Cannot send columns\n");//error
exit(EXIT_FAILURE);
}
else
{
printf("%d has Sent \n",i);
}

free(temp);

}

}
else if(p[i].pid==0)
{
fflush(stdout);

/*Alocating Spaces*/
row=calloc(data1_d.length,sizeof(int));//for rows
ans=calloc(data3_d.length,sizeof(int));//for answer
col=calloc(data2_d.length,sizeof(int *));//for columns

/*If cannot alocate at least on of them*/
if(row==NULL && col==NULL && ans==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}

/*Allocate space for receiving column matrix*/
for(j=0;j<data2_d.length;j++)
{
col[j]=calloc(data2_d.height,sizeof(int));
if(col[j]==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}
}

/*Reading a line if not then it shows the apropriate message and exits*/
if(read(p[i].from_father[0],row,data1_d.length*sizeof(int))<=0)
{
fprintf(stderr,"No data read\n");
exit(EXIT_FAILURE);
}

/*Reading Columns*/
for(j=0;j<data2_d.length;j++)
{
if(read(p[i].from_father[0],(void *)col[j],data2_d.height*sizeof(int))<data2_d.height*sizeof(int))
{
fprintf(stderr,"No data read i=%d j=%d\n",i,j);
exit(EXIT_FAILURE);
}

}

/*Calculating row*/
for(k=0;k<data3_d.length;k++)
{
ans[i]=iMatxmult(row,col[k],data1_d.length,NULL);
}


/*Sending final result*/
if(write(p[i].from_child[1],ans,data3_d.length*sizeof(int))<(data3_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot send final result\nBye\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
else if(p[i].pid<0)
{
fprintf(stderr,"Fork failed");
exit(EXIT_FAILURE);
}
}

k=0;
while(k<data1_d.height)
{
pid=wait(NULL);

for(j=0;j<data3_d.height;j++)
{
if(pid==p[j].pid)
{
/*Reading result*/
if(read(p[j].from_child[0],result[j],data3_d.length*sizeof(int))<=0)
{
fprintf(stderr,"Cannot fetch final table\n");
exit(EXIT_FAILURE);
}
else
{
printf("Child sucessfully read data\n");
}
k++;
pid=0;
}
}
}

/*Printing results*/
puts("Printing Final result\n");
printIntMatrix(result,data3_d.height,data3_d.length);
return 0;
}


pipe.h: περιέχει μια χρήσιμη δομή για το test1.c
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef PIPEH
#define PIPEH
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include"MaxMul.h"
#include"header.h"
/*With this struct I bring all together the pids and the pipes*/
typedef struct
{
pid_t pid;//PID using for fork() function
int from_father[2];//Pipe that father sends data to child from father[0]X is the data and from father[1][X] is control
int **from_father_col;//pipe that I use to send columns
int from_child[2];//Pipe that sends the child to the father
}pipe_s;


#endif


MaxMul.h : Έχει χρήσιμες συναρτήσεις για να υπολογίζει τον τελικό πίνακα του γινομένου και να τυπώνει έναν δισδιάστατο πίνακα
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef MAXMUL_
#define MAXMUL_
#include<stdlib.h>
#include<stdio.h>

typedef struct{
unsigned int height;//Pli8os grammwn
unsigned int length;//Pli8os Stilwn
}dimensions;

/*Epistrefei enan pinaka me tis times tis col stilit tou pinaka matrix*/
int * column(int **matrix,int col,int height);

/*Ektelei ton pollaplasiasmo tis row grammis kai tis col stilis*/
int iMatxmult(int row[], int col[],unsigned int size,int * result);

/*Kataskeuazei ton teliko pinaka kai epistrefei to mege8ow tou telikou pinaka elegxontas an ginetaqi o pollaplasiasmos twn pinakwn*/
int **piliko(dimensions a,dimensions b,dimensions *result);

/*Typwnei enan height*length disdiastato pinaka*/
void printIntMatrix(int **matrix,int height,int length);
#endif


MaxMul.c Οι υλοποίηση των συναρτήσεων του MaxMul.h
Spoiler: show
Κώδικας: Επιλογή όλων
#include "MaxMul.h"
int * column(int **matrix,int col, int height)
{
int *colymn=calloc(height,sizeof(int)),i;

if(colymn!=NULL)
{
for(i=0;i<height&&matrix[i]!=NULL;i++)
{

colymn[i]=matrix[i][col];
}
}
return colymn;
}

int iMatxmult(int row[], int col[],unsigned int size,int * result)
{
int i;
int mult=0;
if(row!=NULL && col!=NULL)
{
for(i=0;(unsigned)i<size;i++)
{
mult+=row[i]*col[i];
}
return mult;
}
}

int **piliko(dimensions a,dimensions b,dimensions *result)
{
int **res,i;
if(a.length!=b.height)
{
return NULL;
}
result->height=a.height;
result->length=b.length;
res=calloc(result->height,sizeof(int *));
for(i=0;(unsigned)i<result->height;i++)
{
res[i]=calloc(result->length,sizeof(int));
}
return res;
}

void printIntMatrix(int **matrix,int length,int height)
{
int i,j;
for(i=0;i<length;i++)
{
for(j=0; j<height ; j++)
{
printf("%d\t",matrix[i][j]);
}
putchar('\n');
}
}


header.h Το Header με την δήλωση της συνάρτησης όπου χρησιμοποιεί το newload.c
Spoiler: show
Κώδικας: Επιλογή όλων
#ifndef HEADER
#define HEADER
#include<stdlib.h>
#include<stdio.h>
#include "MaxMul.h"

int ***load(const char *path,dimensions *data1_d,dimensions *data2_d);
#endif


newload.c Φορτώνει 2 δισδιάστατους πίνακες από το αρχείο
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#include "MaxMul.h"

int ***load(const char *s,dimensions *data1_d,dimensions *data2_d){

FILE *fp = fopen(s,"r");/*Oppening a file*/

/*i,j variavble for traversing 2d array*/
int i,j;

/*
A= we neeed it to make a matrix of 2d arrays
buffer = temporary storage buffer of 2d arrays
*/

int ***A=NULL,**buffer=NULL;

fscanf(fp,"%d %d",&data1_d->height,&data1_d->length); //reading Dimentions from file

A=(int ***)malloc(2*sizeof(int **)); //Allocating 2 2d arrays

buffer = (int**)malloc(sizeof(int*)*data1_d->height); //Allocating temporary storage

if(A!=NULL)
{
A[0] = (int**)malloc(sizeof(int*)*data1_d->height);//Allocating first array
}

if(A[0]==NULL)
{
return NULL;
}

/*More allocation of the array*/
for(i=0;i<data1_d->height && A[0] !=NULL ;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data1_d->length);
A[0][i] = (int*)malloc(sizeof(int)*data1_d->length);

if(buffer[i]==NULL && A[0][i]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}
}

/*Filling the 2d array with data from the file*/
for(i=0;i<data1_d->height;i++)
{

for(j=0;j<data1_d->length;j++)
{
fscanf(fp,"%d",&buffer[i][j]);
A[0][i][j] = buffer[i][j];
}
}

free(buffer); //free buffer

fscanf(fp,"%d %d",&data2_d->height,&data2_d->length); //reading dimention for the second array



buffer = (int**)malloc(sizeof(int*)*data2_d->height); //reallocating buffer

A[1] = (int**)malloc(sizeof(int*)*data2_d->height);//Allocating the second matrix

if(buffer==NULL && A[1]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}

for(i=0;i<data2_d->height;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
A[1][i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
}

/*Filling second matrix*/
for(i=0;i<data2_d->height;i++)
{

for(j=0;j<data2_d->length;j++)
{

fscanf(fp,"%d",&buffer[i][j]);
A[1][i][j] = buffer[i][j];
}
}


/*Prepating for end*/
free(buffer);
fclose(fp);


return A;//return final Matrix



}


Τα δεδομένα τα παίρνει από το αρχείο:

Spoiler: show
Κώδικας: Επιλογή όλων
2 3
11 2 3
4 5 6
3 2
7 -12
-9 1
2 3


Αυτό όπου κάνει εν ολίγοις το πρόγραμμα είναι να παίρνει 2 πίνακες και να τους Πολλαπλασιάζει με κατανεμημένο τρόπο χρησιμοποιώντας διεργασίες παιδιά και pipes. Κάθε διεργασία παιδί υπολογίζει μια γραμμή του τελικού πίνακα του γινομένου.Αλλά το πρόβλημα είναι ότι το τελικό αποτέλεσμα είναι σωστό και τα παιδιά υπολογίζουν σωστά την εκάστοτε γραμμή αλλά η διεργασία πατέρας δεν παίρνει τα σωστά δεδομένα.... Γιατί?
ΔΕΝ ΑΝΤΕΧΩ ΑΛΛΟ :cry: :cry: :cry:


Μόλις είδα το ποστ σου, και απ' ό,τι κατάλαβα δεν κάνεις καλό συγχρονισμό μεταξύ των διεργασιών. Δλδ, δεν ξέρεις με ποια σειρά γράφουν οι διεργασίες στο pipe, κι εσύ στη διεργασία-γονέα περιμένεις να διαβάσεις με τη σειρά. Οπότε, θα πρότεινα να χρησιμοποιήσεις μια μέθοδο συγχρονισμού, πχ σημαφόρους.
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

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

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

cron