为什么我的c代码不像它应该的那样在结尾添加正确的空零,并不断打印出代码?

izkcnapc  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(132)

我不知道为什么我的代码看起来不能正常工作。我正在从一个文件中阅读,并抓住每一行,然后从那里我使用我自己的函数来尝试和分解每一行,并将它们添加到一个结构中的字符数组,然后将这些结构添加到一个数组中。但无论出于什么原因,当我试图单独打印出所有信息的单个值时,不管出于什么原因,即使我的函数strsub应该在末尾添加一个“\0,”它似乎没有这样做。所以每次我把指针传递到每个字符变量的起始位置时,它不会停止,直到整个结构结束,所以它开始打印出整个字符串,然后打印出越来越少的字符串。这是我真正的问题还是我遗漏了其他东西?
这是我到目前为止的代码。我第一次只是尝试创建一个结构体,并在每次传递时填充数组,但不幸的是我遇到了同样的问题。

#define _CRT_SECURE_NO_WARNINGS // Since I want to strictly use ANSI C and not Microsoft C without getting the warning message, I'm adding this line of code before I include header files.
#include <stdio.h>              // "#include" includes the contents of another file, commonly called header file, into the source code file.
#include <string.h>
#define MAX 100
FILE *fp, *csit;

void strsub(char buf[], char sub[], int start, int end);
void printArray(struct trainCartrain[]);

struct trainCar {
    char car[10];
    char type[2];
    char weight[6];
    char length[3];
    char horsepower[3];
    char numberInTrain[4];
};

int main() {

    struct trainCar ar[7];
    struct trainCar train;

    // test and open input file and output file.; 
    
    if (!(fp = fopen("train.txt", "r"))) {
        printf("train.txt could not be opened for input.");
        exit(1);
    }
    if (!(csit = fopen("csit.txt", "w"))) {
        printf("csit.txt could not be opened for output.");
        exit(1);
    }
 
    int i = 0;
    char buf[MAX];

    while (!feof(fp)) {
        fgets(buf, MAX, fp);
        strsub(buf, train.car, 0, 9);
        strsub(buf, train.type, 10, 11);
        strsub(buf, train.weight, 12, 17);
        strsub(buf, train.length, 18, 20);
        strsub(buf, train.horsepower, 21, 23);
        strsub(buf, train.numberInTrain, 24, 27);
        
        printf("%s", train.car);
        printf("%s", train.type);
        ar[i] = train;
        i++;
    }

    printArray(ar);

    fclose(csit);
    fclose(fp);
    return 0;
}
void strsub(char buf[], char sub[], int start, int end) { //strsub () grabs a substring, sub, from a string, buf, given the start and end index within the string.
    int i, j;
    for (j = 0, i = start; i <= end; i++, j++) {
        sub[j] = buf[i];
    }
    sub[j] = '\0'; 
    //end with the null terminator character that signifies the end of a string.
}

我的文件小而简单,文本文件

Boxcar    D 44000 55 16 45
Hopper    B 23000 62 18 33
Tanker    G 15000 45 30 12
Autocar   A 30000 37 23 6
Livestock L 56500 50 18 19
Coalcar   C 49300 53 22 100
Flatcar   F 18000 66 15 25

打印出来的是

Boxcar    D 44000 55 16 45
D 44000 55 16 45
44000 55 16 45
55 16 45
16 45
45
Hopper    B 23000 62 18 33
B 23000 62 18 33
23000 62 18 33
62 18 33
18 33
33
Tanker    G 15000 45 30 12
G 15000 45 30 12
15000 45 30 12
45 30 12
30 12
12
Autocar   A 30000 37 23 6
A 30000 37 23 6
30000 37 23 6
37 23 6
23 6
6
Livestock L 56500 50 18 19
L 56500 50 18 19
56500 50 18 19
50 18 19
18 19
19
Coalcar   C 49300 53 22 100
Flatcar   F 18000 66 15 25C 49300 53 22 100
Flatcar   F 18000 66 15 2549300 53 22 100
Flatcar   F 18000 66 15 2553 22 100
Flatcar   F 18000 66 15 2522 100
Flatcar   F 18000 66 15 25100
Flatcar   F 18000 66 15 25Flatcar   F 18000 66 15 25F 18000 66 15 2518000 66 15 2566 15 2515 2525

有人能解释一下我做错了什么吗?我也必须为我的类使用这个函数strsub。
我只是想让它每次都打印出单个字符数据而不是整个字符串。我想这是结尾处的终止零的问题,当我试着调试时,它似乎出于某种原因没有添加这个。我不知道为什么,如果这是问题所在的话。

vaqhlq81

vaqhlq811#

strsub(buf, train.car, 0, 9);在循环中访问索引为09train.car,然后在循环外访问索引为10train.car,但这已经超出了char car[10];的范围。
解决方法:
将所有数组的大小增加1,以便为字符串的0-终止符留出空间。
还可以查看Why is “while( !feof(file) )” always wrong?。它与您的问题无关,但您可能会在接下来的几分钟内遇到该问题。
代替

while (!feof(fp)) {
    fgets(buf, MAX, fp);
    ....
}

使用了

while (fgets(buf, MAX, fp)) {
    ....
}

您在void printArray(struct trainCartrain[]);中遗漏了一个空格。它应该是void printArray(struct trainCar train[]);,并移到struct trainCar定义之后。
您还必须为#include <stdlib.h>才能使用exit(1);

相关问题