Προβλημα με την fscanf

tzimakos13 | Τετ, 02/09/2011 - 02:10 | 2' | 5

Καλησπερα.
Θα ηθελα παρακαλω να μου πειτε που βρισκετε το προβλημα το παρακατω κομματι κωδικα
στα αποτελεσματα του terminal μου βγαζει σωστα αποτελεσματα μεχρι την πρωτη fscanf και μετα segmentation fault

Αυτο που προσπαθησα να κανω ειναι να διαβασω απο αρχειο .txt τους αριθμους του πινακα διαχωριζοντας την 1η fscanf ως το διαβασμα του συνολικου αριθμου των εξισωσεων προς επιλυση.
Το προβλημα ειναι πως αφου ανοιξω το αρχειο ο compiler χτυπαει στο οτι η fscanf περιμενει int * αλλα λαμβανει int **. Προσπαθησα να το λυσω αλλα δεν μπορεσα.
Το ιδιο προβλημα υπαρχει και με την frpintf.

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

int main()
{
        int num, i, j;
    int p[1];
    int **pinakas2;
        FILE *fp;
       
        fp=fopen("Gauss_in.txt", "r");
        fscanf(fp, "%d", p);
    printf("you have inserted %d equations\n", p[0]);
    pinakas2=(int **)malloc(p[0]*sizeof(int));
    for(i=0;i<p[0];i++)
      pinakas2=(int *)malloc((p[0]+1)*sizeof(int));
    i=0;
    j=0;
         while (fscanf(fp, "%d", &num) == 1)
        {
      pinakas2[j]=num;
      j=j+1;
      if(j<=p[0])
        i=i+1;
        }
        fclose(fp);

Δώσε αστέρια!

MO: (ψήφοι: 0)

Σχόλια

Λοιπον εγω είδα τα παρακάτω λάθη και σου δίνω τα σωστά σύμφωνα με τον κώδικά σου.

fscanf(fp, "%d", p[0]);    /* το σκέτο p δεν είναι τίποτα */

pinakas2=(int **)malloc(p[0]*sizeof(int*));  

while (fscanf(fp, "%d", num) == 1)    /* το & δεν χρειάζεται */

Το segmentation fault σημαίνει γενικά ότι βγαίνεις κάπου εκτος μνήμης.

Καλο είναι μετα την fclose(fp); και πριν τερματίσει το πρόγραμμά σου να βάλεις ένα free(pinakas2);

Επίσης καλο είναι να βάλεις έναν έλεγχο για το τι επιστρέφει η fopen αν δηλαδή βρήκε το συγκεκριμένο αρχείο ή οχι. Παρακάτω σου γράφων τον κώδικα που το κάνει.

if ( fp == NULL) {
     printf("File does not exist in this directory.\n");
     return -1;
}

Για οτιδήποτε απορία εδώ είμαστε. Wink

@tzimakos13: Φίλε μου, πες μας κ τί ακριβώς περιέχει το αρχείο. Αν κατάλαβα καλά, κάποιο (τετραγωνικό?) πίνακα. Πόσες γραμμές/στήλες; Πώς είναι γραμμένα τα δεδομένα; Τί χωρίζει τις γραμμές/στήλες;

@osripper: δυστυχώς δεν έχεις δίκιο φίλε μου. Το "p" δεν είναι "τίποτα" (!), είναι pointer. Βασικά, αν p είναι array κάποιου τύπου, τότε το να γράψεις σκέτο "p", χωρίς index, είναι ισοδύναμο με "&p[0]" δηλαδή είναι η πρώτη διεύθυνση μνήμης όπου αρχίζει ο πίνακας p. Η scanf από την άλλη θέλει ΠΑΝΤΑ pointer για το μέρος όπου θα γράψει, οπότε στη πρώτη περίπτωση αρκεί το "p" (για να δείξει στη πρώτη θέση του πίνακα), ενώ στη δεύτερη scanf, αφού το num είναι είναι ακέραιος, χρειάζεται να το δώσεις ως "&num" (δηλαδή, "εκεί που είναι αποθηκευμένη η μεταβλητή num"). Οπότε κ τα δύο σωστά τα έγραψε ο tzimakos13.

Από εκεί κ πέρα, ο osripper το είπε σωστά, το ότι η fscanf σκάει σημαίνει ότι πάει να διαβάσει/αποθηκεύσειι αλλού για αλλού. Νομίζω (χωρίς να είμαι σίγουρος κοιτώντας το απλά) ότι το λάθος είναι στη γραμμή:

while (fscanf(fp, "%d", &num) == 1)

Νομίζω ότι αν θες να διαβάζεις μέχρι το τέλος του αρχείου, το σωστό είναι:
while (fscanf(fp, "%d", &num) != EOF).

Αν δεν είναι αυτό, τότε 99% έχει να κάνει με τα περιεχόμενα του αρχείου που διαβάζεις, οπότε πες μας περισσότερα.

Από το man page της fscanf:
RETURN VALUE
       These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
      
       The  value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs.  EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.

gnu_labis είναι σωστό αυτό που λες για το "p" απλά πιστεύω ότι είναι καλύτερο να γράφουμε την μεταβλητή που θέλουμε ακριβώς γιατί αν ο πίνακας δεν είχε 1 θέση ???  Πολύ σωστά λέει ο φίλος gnu_labis για το EOF.

Εγώ συνεχίζω  να πιστεύω ότι το πρόβλημα είναι στην malloc γιατί την έχει γράψει λάθος ο tzimakos13. Θέλει να δεσμεύσει ένα πίνακα απο pointers και βάζει λάθος το μέγεθος.

Καταρχας να σας ευχαριστησω για τις απαντησεις :)

Μετα απο δοκιμες βρηκα το πως θα εκχωρησω με την fscanf

καπως ετσι :

 fp=fopen("Gauss_in.txt", "r");
        fscanf(fp, "%d", &numEQ);
    printf("you have inserted %d equations\n", numEQ);
    pinakas=(int **)malloc(numEQ*sizeof(int));
    for(i=0;i<numEQ;i++)
      pinakas=(int *)malloc((numEQ+1)*sizeof(int*));
  
        for (i = 0; !feof(fp) && i < numEQ; ++i)
    {
          for (j = 0; !feof(fp) && j < (numEQ+1); ++j)
      {
            fscanf(fp, "%d", &pinakas[j]);
            fprintf(stdout, "%d ", pinakas[j]);
      }
    }
        fclose(fp);
      

Το segmentation fault ακομα ψαχνω...

το προγραμμα θα επερνε τους συντελεστες του Χι , ι=0,1,2,3,..., και θα τους εβαζε σε εναν πινακα στον οποιον θα εφαρμοζε GAUSS και θα εδινε τις λυσεις σε ενα αλλο αρχειο(GAUSS_out.txt)

το GAUSS_in.txt θα ηταν της μορφης
α
χ1
χ2
χ3
χ4
.
.
.
.

το α θα ειναι ο αριθμος των εξισωσεων προς επιλυση
αυτο ειναι το προγραμμα