Killer_B
Killer_B

Reputation: 63

how to rewind to the beginning of a line while reading from a file. c

other than counting how many spaces i moved. is there a simple way to get the buffer back to the beginning of a line for reading? am trying to read in strings and then go back to read a different string and numbers. its not in order so i have to go back and look for them specifically. how do i do it.

i use rewind(fp); but that goes back to the beginning of the file.

also am trying to read in integers after the strings. the problem is its hard to read in double, triple digit numbers. i was able to do. but as you see the function down there is a mess. is there an easier way to read multi-digit integers;

void get_total(FILE*fp, int* ptotal, int* pscores, int* pnum_quiz){

    char c;

    int i = 0;

    int total=0;

    int digits; 
    int first, second, third;

    *pnum_quiz = 0;

    int number_of_conversions;

    number_of_conversions = fscanf(fp, "%c", &c);

    while (isdigit(c) || isspace(c) && c !='\n' && c !=NULL && number_of_conversions!=0 && number_of_conversions !=EOF){


        if (isspace(c)){
            number_of_conversions = fscanf(fp, "%c", &c);

        }

        else if (isdigit(c)){
            first = c - '0'; // convert a character integer to integer

            *(pscores + i) = first;
            i++;

            number_of_conversions = fscanf(fp, "%c", &c);

            digits = 1;

            if (isdigit(c)){

                second = c - '0';

                *(pscores + i) = second;

                i++;

                number_of_conversions = fscanf(fp, "%c", &c);

                digits = 2;

                if (isdigit(c)){

                    third = c - '0';

                    *(pscores + i) = third;
                    i++;

                    digits = 3;
                }
                else{
                    fseek(fp, -1, SEEK_CUR);
                    *(pscores + i) = -1;
                    i++;
                }


            }
            else{
                fseek(fp, -1, SEEK_CUR);
                *(pscores + i) = -1;
                i++;
                *(pscores + i) = -1;
                i++;
            }

            if (digits==3){
                total = total + (first * 100) + (second * 10) + third;
            }
            else if (digits==2){
                total = total + (first * 10) + second;
            }
            else {
                total = total + first;
            }


            number_of_conversions = fscanf(fp, "%c", &c);



        } 

        number_of_conversions = fscanf(fp, "%c", &c);

        *pnum_quiz = *pnum_quiz + 1;
    }

    *ptotal = total;

}

Upvotes: 2

Views: 3776

Answers (1)

M Oehm
M Oehm

Reputation: 29116

You could go fseeking backwards through the file, but that's not a good option, in my opinion.

Just read in the whole line and store it in a char buffer. Your code does that with repeated calls to fscanf(fp, "%c", &c), which is needlessly clumsy. There is already a function that does this, fgets:

char line[80];

while (fgets(line, sizeof(line), fp) != NULL) {
    // Now scan line instead of fp
}

Now you can parse line depending on your iput format: sscanf(line, ..) if you have a fixed format. strtok repeatedly if you need to extract tokens, and so on. (You don't show the format of your input, but there's probably a function to deal with it better than coding it by hand.)

One potential problem with fgets is that you need to specify a maximum length, which may not be suitable if you can have arbitrarily long lines. There's also the annoyance of the new-line character that's left at the end of each line.

Upvotes: 2

Related Questions