raphnguyen
raphnguyen

Reputation: 3605

Reading data from a file

I'm currently getting a run-time check failure #2 - stack around the variable city was corrupted. The input file that is read is formatted like so:

Betty, 12 Main Street, North Elmo, NC 29801, 2000.20
Joe, 16 Maple Blvd., Stumptown, GA, 33125, 4000.40
Frank, 100 Avent Ferry, Raleigh, NC 27606, -3000.30

How can I fix this error?

int main(int argc, char *argv[]) {
    int c, i, zip;
    FILE *fp;
    char name[20], address[50], city[19], state[3];
    float balance;

    for (i = 1; i < argc; i++) {
        fp = fopen(argv[i], "r");
        if (fp == NULL) {
            fprintf(stderr, "cat: can't open %s\n", argv[i]);
            continue;
        }

        while ((c = getc(fp)) != EOF) {
            fscanf(fp, "%s%s%s%s%d%f", &name, &address, &city, &state, &zip, &balance);
        }

        printf("%s%s%s%s%d%f\n", name, address, city, state, zip, balance);
        fclose(fp);
    }

    return 0;
}

Update:

Thanks for all of the help thus far. What I have done now is I have created a struct with each person in the struct containing a name, address, and balance. I just changed the previous statements to pass variables to a struct person p and then created an insert() method that inserts p into a struct person list.

while (fgets(line, sizeof(line), fp) != NULL) {
        p = malloc(sizeof(struct person));
        sscanf(line, "%19[^,], %49[^,], %18[^,], %2[^ ] %d, %lf\n", p->name, p->address, p->city, p->state, &p->zip, &p->balance);
        printf("got [%s], [%s], [%s], [%s], [%d] and [%9.2f].\n", p->name, p->address, p->city, p->state, p->zip, p->balance);
        insert(p);
    }

I am trying to insert person into the list in alphabetical order and tried doing this by using strcmp. Upon running my program with this method, it hangs and stops execution at the first insert. Looking for help on where I went wrong on my insert() method.

void insert(struct person *p) {
struct person *cur, *prev;
int result = 0;

for (cur = list, prev = NULL, result = strcmp(p->name, cur->name); cur != NULL && result > 0; prev = cur, cur = cur->next, result = strcmp(p->name, cur->name));

if (cur != NULL && result == 0) {
    printf("-------------------------\n"
        "DUPLICATE RECORD: %s\n"
        "-------------------------\n", p->name);
    free(p);
    return;
}

p->next = cur;
if (prev == NULL) {
    list = p;
}
else {
    prev->next = p;
}
}

I tested this method out without the strcmp(). I just compared with p->name > cur->name and it was able to insert and print out the list just fine with my print() method. The only problem was the persons were not sorted alphabetically, so I went back and tried to implement strcmp().

Upvotes: 0

Views: 630

Answers (2)

pmg
pmg

Reputation: 108988

I guess your stack problem comes from trying to put more characters into state than it can hold.

You defined state as capable of holding 3 characters: 2 regular characters and 1 null terminator. Your fscanf statement when presented with the example input, tries to write 8 characters (7 regular and 1 null terminator) in that space for 3 characters.

This invokes what is called undefined behaviour. One way undefined behaviour can manifest itself is by corrupting variables.


Edit

To limit scanf to a fixed number of characters, use the maximum field width in the conversion specification:

char buf[42];
scanf("%41s", buf); /* reads at most 41 non whitespace characters to `buf`
                    ** and appends a null terminator,
                    ** for a maximum total of 42 characters */

Upvotes: 0

user2100815
user2100815

Reputation:

This:

fscanf(fp, "%s%s%s%s%d%f", &name, &address, &city, &state, &zip, &balance);

should be:

fscanf(fp, "%s%s%s%s%d%f", name, address, city, state, &zip, &balance);

Upvotes: 4

Related Questions