簡體   English   中英

Segfault使用fgets()從文件復制到字符串

[英]Segfault copying from file to string with fgets()

我有一個文本文件,其中包含日期,時間,小時,日期,如下所示:

aaaa rrr rrr rrr 1111111111111111 2222222222222222
aaaa rrr rrr rrr 3333333333333333 4444444444444444
bbbb rrr rrr rrr 5555555555555555 6666666666666666
bbbb rrr rrr rrr 6666666666666666 7777777777777777
cccc . . . . .
.
.
.

aaaabbbb0001 0002等等, rrr線是無關緊要的, 11...11 rrr 22...22等是日期和時間,即2005-11-03 04:50

所以,我有3個malloc'ed字符串數組:

  • 啜飲aaaabbbb
  • STD為11..11133..33等(第一行)
  • ETD為22..22244..44等。(第二行)

我想要做的是存儲:

  • 所有不同的aaaa,bbbb in sip [number_of_them]
  • 11...11 in std [number_of_them]
  • etd中的44...44 [他們的數量]

注意:例如 - > sip [0]中的aaaa ,std [0]中的11...11和etd [0]中的44...44

每次aaaa變為bbbb等等 - > bbbb to sip [1], 55...55 to std [1]和77...77 to etd [1]

不幸的是,我的代碼中出現了一些錯誤:

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

main () {

    char** sip = malloc(count*sizeof(char*));            // Array for storing flight combinations
    for (i=0; i<count; i++) sip[i] = malloc(5);

    char** std = malloc(count*sizeof(char*));            // Array for storing starting time and date
    for (i=0; i<count; i++) std[i] = malloc(17);

    char** etd = malloc(count*sizeof(char*));            // Array for storing ending time and date
    for (i=0; i<count; i++) etd[i] = malloc(17);

    char* temp = malloc(5);     // Temporary string for passing over irrelevant charactersf

    int a=0, lines = 1;

    char str[2];
    FILE *fp = fopen("test.txt", "rb");{
        while (!feof(fp)) {
            fgets(sip[a],  5, fp);                // SP is stored

            fgets(std[a], 14, fp);                // Pass over irrelevant characters
            fgets(std[a], 17, fp);                // STD is sotred

            fgets(etd[a],  2, fp);                // Pass over irrelevant characters
            fgets(etd[a], 17, fp);                // Temporary ETD is stored

            fgets(temp, 3, fp);                   // Pass over newline
            fgets(temp, 5, fp);                   // SP is stored to check if it has changed

            while (strcmp(temp, sip[a]) == 0) {   // Check if SP has changed
                fgets(etd[a], 16, fp);            // Irrelevant characters
                fgets(etd[a], 16, fp);            // Irrelevant characters

                fgets(etd[a++], 17, fp);          // Correct ETD is stored here, starting from 31st character
                fgets(temp, 3, fp);               // Pass over newline
                fgets(temp, 5, fp);               // SP is stored to check if it has changed

            }
        }
    }

printf(" %s \n %s \n %s \n ", sip[0], std[0], etd[0]);        // Printf to check result    

}

示例文本文件如下所示:

0021 918 ATH SKG 2011-11-02 20:00 2011-11-02 20:55
0021 901 SKG ATH 2011-11-03 05:00 2011-11-03 05:55
0022 518 ATH HER 2011-11-02 20:00 2011-11-02 20:50
0022 501 HER ATH 2011-11-03 05:00 2011-11-03 05:50
0023 325 ATH CAI 2011-11-02 22:50 2011-11-03 00:45
0023 326 CAI ATH 2011-11-03 01:45 2011-11-03 03:45
0024 301 ATH TLV 2011-11-02 23:15 2011-11-03 01:10
0024 302 TLV ATH 2011-11-03 04:00 2011-11-03 06:10
0025 530 ATH CHQ 2011-11-01 03:50 2011-11-01 04:40
0025 531 CHQ ATH 2011-11-01 05:20 2011-11-01 06:10
0026 175 ATH SKG 2011-11-01 07:05 2011-11-01 08:00
0026 175 SKG MUC 2011-11-01 08:40 2011-11-01 10:45
0026 176 MUC SKG 2011-11-01 11:35 2011-11-01 13:35
0026 176 SKG ATH 2011-11-01 14:15 2011-11-01 15:10

預期的答案是:

0021 2011-11-02 20:00 2011-11-03 05:55
0022 2011-11-02 20:00 2011-11-03 05:50
0023 2011-11-02 22:50 2011-11-03 03:45
0024 2011-11-02 23:15 2011-11-03 06:10
0025 2011-11-01 04:40 2011-11-01 06:10
0026 2011-11-01 07:05 2011-11-01 15:10

嘗試一下:

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

void die(const char *msg) {
    fprintf(stderr, "Error: %s.\n", msg);
    exit(EXIT_FAILURE);
}

int main() {
    char line[256];

    FILE *fp = fopen("test.txt", "r");
    if (fp == NULL) die("Can't open file");

    // Count the number of unique first values.
    int count = 0;
    char sp[5], sp_last[5] = {0};
    while (fgets(line, sizeof line, fp)) {
        sscanf(line, "%4s", sp);
        if (strcmp(sp, sp_last) != 0)
          ++count;
        strcpy(sp_last, sp);
    }
    rewind(fp);

    char (*sip)[5]  = malloc(count * sizeof(*sip));
    char (*std)[17] = malloc(count * sizeof(*std));
    char (*etd)[17] = malloc(count * sizeof(*etd));
    char etd_in[17];

    if (fgets(line, sizeof line, fp) == NULL)
        die("Can't read first line");

    for (int i = 0; i < count; ++i) {
        if (sscanf(line, "%4s %*s %*s %*s %16c", sip[i], std[i]) != 2)
            die("Can't scan line (a)");
        std[i][16] = '\0';
        while (fgets(line, sizeof line, fp)) {
            if (sscanf(line, "%4s %*s %*s %*s %*16c %16c", sp, etd_in) != 2)
                die("Can't scan line (b)");
            etd_in[16] = '\0';
            if (strcmp(sp, sip[i]) == 0)
                strcpy(etd[i], etd_in);
            else
                break;
        }
    }

    for (int i = 0; i < count; ++i)
        printf("%s %s %s\n", sip[i], std[i], etd[i]);

    free(sip);
    free(std);
    free(etd);

    return 0;
}

我可以建議一個問題(至少)在這里:

char** sip = malloc(count*sizeof(char*));            // Array for storing flight combinations
for (i=0; i<count; i++) sip[i] = malloc(5);

char** std = malloc(count*sizeof(char*));            // Array for storing starting time and date
for (i=0; i<count; i++) sip[i] = malloc(17);

char** etd = malloc(count*sizeof(char*));            // Array for storing ending time and date
for (i=0; i<count; i++) sip[i] = malloc(17);

你分配了三個字符串數組sipstdetd ,但是你只需要初始化sip元素,每個元素三次。 第二個for循環應該初始化std ,第三個應該初始化etd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM