Saya mencoba membaca file teks bilangan bulat ke dalam array di C.

File teks saya terlihat seperti ini: (12 angka/baris)

5713    6936    8764    6702    8535    8654    8710    8332    4948    7627    5472    5311    
7331    8719    6135    6672    5786    7113    5292    6923    5683    7020    8595    8606    
6837    7003    7415    8372    8429    5726    8323    6442    8672    6488    6932    5884    
6811    7785    7189    5531    6323    8561    8283    5114    6669    7217    8307    6599    
6961    8695    6026    5580    6010    4954    8725    4955    5532    7736    5372    8712    
8343    5375    5931    6449    8223    5844    5931    5307    5436    6405    8599    6302    
8617    8222    5985    8216    5044    5259    6523    7526    8702    5878    7559    5366    
5362    7393    6633    8781    6289    6470    5342    7278    5348    8677    5779    5763    
5718    8678    6406    8774    5931    7324    6819    6393    5027    7545    8385    8795    
8277    8059    6362    6980    5899    5828    6707    7149    5621    7287    5958    6506    
6517    5710    5504    7070    8797    6840    7112    6063    7014    5419    7514    7431   

File sebenarnya memiliki 1000 angka keseluruhan

Saat ini, saya menggunakan kode berikut:

int main(void){

    FILE *my_file;
    my_file = fopen("seals.txt", "r");
    size_t size = word_conter(my_file);

    int weight = 0;
    int seals[size];

    int i;
    for(i = 0; i < size; i++){
        if(fscanf(my_file, "%1d", &weight) == 1)
            seals[i] = weight;
        else break;
    }

    for(i = 0; i < size; i++){
        printf("%d\t %d\n", i, seals[i]);
    }

    
    fclose(my_file);    
    return 0;
}

EDIT: Ini word_counter :

size_t word_conter(FILE *my_file){
    
    if(my_file == NULL){
        perror("Error in file");
        exit(1);
    }

    size_t counter = 0, in_word = 0;
    char ch;

    while((ch = fgetc(my_file)) != EOF){

        if(ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0'){
            if(in_word){
                in_word = 0;
                counter++;
            }
        }
        else in_word = 1;
    }

    return counter;
}

Sayangnya, output saya adalah:

0    245589760
1    1
2    1
3    0
4    -497513808
5    32766
6    245022469
7    1
8    -497513808
9    32766
10   245022268
11   1
12   1
13   0
14   224894352
15   1
16   -497513744
17   32766
18   244994643
19   1
20   245557328
21   1
22   224894352
23   1
24   224879992
25   1
26   0
27   0
28   245584536
29   1
30   245616784
31   1
32   -497513712
33   32766
34   245024298
35   1
36   245557328
37   1
38   -799666472
39   22978
40   -497510096

Begitu seterusnya hingga 999.

Saya telah mencoba menggunakan keduanya: fscanf(my_file, "%1d", &weight) dan fscanf(my_file, "%d", &weight) tetapi keduanya tidak berhasil. Saya telah membaca manual tentang fscanf tetapi masih tidak bisa melakukannya dengan benar.

Bantuan apa pun akan sangat dihargai!

Pengeditan Kedua:

Saya menggunakan rewind() dan itu berhasil!

0
Tal Zichlinsky 29 Desember 2020, 17:05

3 jawaban

Jawaban Terbaik

Penghitung kata kacau pada kasus tepi.

Carilah transisi dari ruang ke non-ruang. Jangan lupa untuk rewind().

size_t counter = 0;
bool in_word = false;
// char ch;
int ch;

while((ch = fgetc(my_file)) != EOF){
   if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0') {  // better: if (isspace(ch)) {
     in_word = false;
   } else {
     if (!in_word) counter++;
     in_word = true;
   }
}
rewind(my_file); // reset to the beginning

return counter;

Lebih baik lagi, cukup buka file dua kali dengan format sama.

size_t counter = 0;
while (fscanf(my_file, "%d", &weight) == 1) {
  counter++;
}
rewind(my_file); // reset to the beginning
2
chux - Reinstate Monica 29 Desember 2020, 15:09

Singkatnya, ini disebabkan oleh membaca file data dua kali berturut-turut tanpa memanggil rewind().

Masalah terjadi ketika fscanf() membaca file untuk kedua kalinya tanpa memutar ulang. (bacaan pertama ada di fungsi word_conter()):

        if(fscanf(my_file, "%d", &weight) == 1)//2nd read on one file descriptor
             seals[i] = weight;//program flow never gets here
        else break;

Ini menghasilkan aliran eksekusi yang melompat langsung ke else break;, kemudian melanjutkan pengulangan pada printf() dan mengeluarkan larik yang tidak diinisialisasi: int seals[size];

Selain itu, fungsi word_conter rentan terhadap berbagai inkonsistensi format data yang mungkin ada dalam file yang sedang dibacanya. Sarankan untuk menelusuri kode dalam debugger untuk mengkarakterisasi dengan tepat bagaimana hal ini dapat berkontribusi pada masalah.

Saran saya adalah untuk memanggil fopen() dan fclose masing-masing sekali di dalam word_counter, lalu panggil kembali keduanya di fungsi utama. Versi size_t word_conter(FILE *my_file) yang difaktorkan ulang ini mendukung pendekatan ini. (ditulis untuk mengakomodasi file yang berisi 12 angka per baris sesuai yang disebutkan dalam komentar):

size_t word_counter(char *filename)
{
    char line[260] = {0};
    char *tok = NULL;
    int count = 0;
    FILE *fp = fopen(filename, "r");
    if(fp)
    {
        while(fgets(line, sizeof(line), fp))
        {
            tok = strtok(line, " \n");
            while(tok)
            {
                count++;
                tok = strtok(NULL, " \n");
            }
            memset(line, 0, sizeof(line));
        }
        fclose(fp);
    }
    return count;
}

Disebut utama sebagai:

size_t size = word_counter("seals.txt");

Ada juga contoh penggunaan penentu format dapat memanggil perilaku tidak terdefinisi

Untuk:

int weight = 0;

Penentu format yang benar adalah "%d". Perubahan apa pun:

if(fscanf(my_file, "%1d", &weight) == 1)

Untuk:

if(fscanf(my_file, "%d", &weight) == 1)    

Atau ubah:

   int weight = 0;
   int seals[size];

Untuk:

   long weight = 0;
   long seals[size];

(%ld hanya digunakan untuk long.)

Mengatasi masing-masing kemungkinan akan mengatasi masalah yang Anda lihat. (Namun, karena word_conter() tidak ditampilkan secara mendetail, mungkin ada masalah lain.)

2
ryyker 29 Desember 2020, 16:02

Coba ganti if(fscanf(my_file, "%1d", &weight) == 1) dengan if(fscanf(my_file, "%d", &weight) != EOF)

0
Yehonatan harmatz 29 Desember 2020, 14:19