περασμα string με δείκτη

Συζητήσεις για γλώσσες προγραμματισμού και θέματα σχετικά με προγραμματισμό.
Post Reply
black7ack
bit level
bit level
Posts: 15
Joined: Sat Apr 17, 2010 2:40 pm

περασμα string με δείκτη

Post by black7ack » Sat Oct 16, 2010 4:20 pm

Λοιπόν στον κώδικα που ακολουθεί (δεν έχω βάλει σχόλια αλλά νομίζω ότι είναι αρκετά κατανοητός) προσπαθώ να συνενώσω τα 2 αρχεία που πέρνω σαν είσοδο και να βάλω την έξοδο στο τρίτο αρχείο.
Τρέχοντας το λοιπόν το πρόγραμμα ενώ δουλεύει για μικρές εισόδους και/ή για μικρούς buffer(15 char max) όταν προσπαθώ να βάλω ως είσοδο ένα μεγαλύτερο αρχείο και να χρησιμοποιήσω μεγαλύτερο buffer τότε δεν περνάει ολόκληρο το string από τη συνάρτηση my_read στην συνάρτηση my_write.
Έχει κανείς καμία ιδέα τι μπορεί να φταίει?

Code: Select all

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int my_read(int fd, char **output){
    char buff[10000];
    ssize_t rcnt;
    
    rcnt = read(fd, buff, sizeof(buff)-1);
    if(rcnt == 0)
        return rcnt;
    if (rcnt == -1){
        perror("read :");
        return rcnt;
    };
    buff[rcnt] = '\0';
    *output = buff;
    return rcnt;
}

int my_write(char *buffer, int fd) {
    size_t len, idx;
    ssize_t wcnt;
    
    idx = 0;
    len = strlen(buffer);
//    printf("string= %s--->", buffer);
    printf("len = %zu \n", len);
    do {
        wcnt = write(fd, buffer + idx, len - idx);
        if (wcnt == -1) {
            perror("write :");
            return 1;
        }
        idx += wcnt;
    }while (idx < len);
    return 0;
}
        
void copyfile (int fd1, int fd2){
    char *buff = NULL;
    
    for(;my_read(fd1, &buff)>0;){
        printf("len = %zu \n", strlen(buff));
        my_write( buff, fd2);
    }
}

int main(int argc, char **argv)
{
    int fd1, fd2, fd3, oflags1, oflags2, mode;
    
    oflags1 = O_RDONLY;
    oflags2 = O_CREAT | O_WRONLY | O_TRUNC;
    mode = S_IRUSR | S_IWUSR;
    fd1 = open(argv[1], oflags1);
    if (fd1 == -1) {
        perror("open1 :");
        exit(1);
    }
    fd2 = open(argv[2], oflags1);
    if (fd2 == -1) {
        perror("open2 :");
        exit(1);
    }
    fd3 = open(argv[3], oflags2, mode);
    if (fd3 == -1){
            perror("open3 :");
            exit(1);
    }
    copyfile(fd1, fd3);
    copyfile(fd2, fd3);
    return 0;
} 
    
    
User avatar
maxthebest
Kilobyte level
Kilobyte level
Posts: 180
Joined: Fri Dec 02, 2005 5:23 pm
Location: Παράδεισος

Re: περασμα string με δείκτη

Post by maxthebest » Sun Oct 17, 2010 8:07 am

1)
*output = buff;

:cry: χιιιιιιιιιιιιιιιιιιιιιιιιιι !!!!! το buff ειναι local μεταβλητη και οταν ολοκληροθει η συναρτηση θα διαγραφει απο την μνημη.
Αρα λοιπον το output δειχνει σε διαγραμμενη μνημη και το προγραμμα σου ειναι εσφαλμενο.

2) Γιατι χρησιμοποιεις συναρτησεις της c αντι της c++ ?

Σιγουρα διαβασες απο αυτα τα c++ tutorial, που κανεις δεν ξερει τι γραφει,
Χρησιμοποιησε το :
http://www.cplusplus.com/doc/tutorial/files/

3)
char buff[10000];
ασε δεν το σχολιαζω, μπορεις να τοποθετησεις μεχρι 10000 χαρακτηρες στον πινακα, buffer overflow αν βαλεις παραπανω.
Ούτοι συνέχθειν, αλλά συμφιλείν έφυν (Αντιγόνη στοίχος 523) =
Δεν γεννήθηκα για να συμμερίζομαι το μίσος , αλλά για να αγαπώ και να με αγαπούν.
black7ack
bit level
bit level
Posts: 15
Joined: Sat Apr 17, 2010 2:40 pm

Re: περασμα string με δείκτη

Post by black7ack » Sun Oct 17, 2010 12:42 pm

Nice! Στην αρχή είχα δοκιμάσει να περνάω στον δείκτη την διεύθυνση ενός πίνακα (buff[]) αλλά τότε δεν πέρναγε τίποτα, συνεπώς δοκίμασα με τον δείκτη σε string (buff) και δούλευε για μικρές εισόδους οπότε θεώρησα πως ο δείκτης για κάποιο λόγο δεν θεωρείτε local μεταβλητή. Αλλά πραγματικά αυτό τα εξηγεί όλα.

Σχετικά με τα υπόλοιπα από την αρχή κώδικα σε c ήθελα να γράψω δεν έχω ασχοληθεί καθόλου με c++ αλλά σίγουρα θα ρίξω μία ματιά στο tutorial. Στην αρχή ο buff ήταν buff[1024] αλλά κάνοντας διάφορες δοκιμές για σε ποιες περιπτώσεις δουλεύει το άλλαξα και ξέχασα να το διορθώσω.

Χίλια ευχαριστώ!

-----
Λοιπόν η πιο γρήγορη και εύκολη λύση που μου πέρασε από το μυαλό είναι ο ορισμός του buff ως static. Γενικά η χρήση static είναι καλή προγραμματιστική συνήθεια? Ποίες παρενέργειες μπορούν να προκληθούν?
Κάθε φορά που τρέχει η my_read δημιουργείται και ένα καινούργιο στιγμιότυπο του buff η χρησιμοποιείται το ίδιο. Με άλλα λόγια υπάρχει περίπτωση σε μεγάλη είσοδο και επειδή ο buff έχει δηλωθεί ως static να εξαντληθεί η στοίβα λόγω των πολλών στιγμιοτύπων του buff?
Last edited by enum21 on Sun Oct 17, 2010 1:36 pm, edited 1 time in total.
Reason: posts merged
Post Reply

Return to “Προγραμματισμός”