reading multiple variable types from single line i

2019-03-04 19:50发布

Alright I've been at this all day and can't for the life of me get this down, maybe you chaps can help. I have a file that reads as follows

1301,105515018,"Boatswain","Michael R.",ABC, 123,="R01"

1301,103993269,"Castille","Michael Jr",ABC, 123,="R03"

1301,103993267,"Castille","Janice",ABC, 123,="R03"

1301,104727546,"Bonczek","Claude",ABC, 123,="R01"

1301,104731479,"Cruz","Akeem Mike",ABC, 123,="R01"

1301,105415888,"Digiacomo","Stephen",ABC, 123,="R02"

1301,106034479,"Annitto Grassis","Susan",ABC, 123,="R04"

1301,106034459,"Als","Christian",ABC, 123,="R01"

And here is my code...

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

#define MAX_NAME 15
#define MAX_SUBSEC 3
#define N 128

//void printArr(struct *students);

struct student{

int term;
int id;
char lastname[MAX_NAME];
char firstname[MAX_NAME];
char subjectname[MAX_SUBSEC];
int catalog;
char section[MAX_SUBSEC];

}students[10];

int main(){

int term;
int id;
char lastname[MAX_NAME];
char firstname[MAX_NAME];
char sub[MAX_SUBSEC];
int cat;
char sec[MAX_SUBSEC];

char fname[N];
FILE *inputf;

printf("Enter the name of the text file: ");
scanf("%123s",fname);

strcat(fname,".txt");

inputf = fopen(fname,"r");

if (inputf == NULL){

     printf("I couldn't open the file for reading.\n");
     exit(0);

}
//TROUBLE HERE!

fscanf(inputf, "%d,%d,%[^,]s", &students[0].term, &students[0].id,students[0].lastname);

printf("%d\n", students[0].term);

printf("%d\n", students[0].id);

printf("%s\n", students[0].lastname);

/*for (j = 1 ; j <= 10-1 ; j++){

    for(k = 0 ; k <= 10-2 ; k++){

        if(students[k] > students[k+1]){

            temp = students[k];
            students[k] = students[k+1];
            students[k+1] = temp;

            }
        }
    }*/

fclose(inputf);

system("pause");

return 0;

}

void printArr(int a[], int tally){

int i;

for(i = 0 ; i < tally ; i++){

 printf("%d ", a[i]);

}

printf("\n");

}

My objective is to take each one of those values in the text file and input it to where it belongs in the struct and subsequently the struct array, but I can't get passed the first 2 ints.

Getting the lastname string, because it is a max of 15 characters, it spills over into the first name string right after it and takes what remaining characters it needs in order to fill up the lastname char array. Obviously I do not want this. As you can see I have tried strtok but it doesnt do anything, not sure what I have to do though as I have never used it before. Also have tried just including all the variables into fscanf statement, but I either get the same output, or it becomes a mess. As it is, I am extremely lost, how do I get these values into the variables they belong?!

EDIT: updated my code, I have gotten a little farther but not much. I can now print out just the last name but can not more farther from there, I cant get to the firstname string or any of the variables beyond it.

5条回答
贼婆χ
2楼-- · 2019-03-04 20:07

I have a question for you... If you want to know how to use a diamond cutter, do you try it and see, or do you consult the manual? The problem here isn't the result of your choice, but your choice itself. Believe it or not, I have answered these questions so often that I'm tired of repeating myself. The answer is all in the manual.

Read the POSIX 2004 scanf manual — or the POSIX 2008/2013 version — and the answer this question and you'll have some idea of what you're not doing that you should be. Even fscanf code should use assert as a debugging aid to ensure the number of items read was correct.

%[^,]s It seems as though there's a mistake here. Perhaps you meant %[^,]. The %[ format specifier is a different format specifier to the %s format specifier, hence in the presumably mistaken code there are two directives: %[^,] and s. The s directive tells scanf to read an 's' and discard it.

查看更多
We Are One
3楼-- · 2019-03-04 20:08

With the fscanf format string "%d,%d,\"%[^\"]\",\"%[^\"]\",%[^,],%d,=\"%[^\"]\"" we can read a whole line's data. Besides, you have to define

char lastname[MAX_NAME+1];
char firstname[MAX_NAME+1];
char subjectname[MAX_SUBSEC+1];
int catalog;
char section[MAX_SUBSEC+1];

— the +1 to account for the terminating '\0' character.

查看更多
爷、活的狠高调
4楼-- · 2019-03-04 20:09

1.There is a syntax error in

while(result != NULL){

      printf(".....);

      ......

}

}//error
  1. fscanf(inputf, "%s", lastname); can't read a line ,fscanf will stop when it comes across an space
查看更多
Evening l夕情丶
5楼-- · 2019-03-04 20:10

fscanf reads one line at a time, and you can easily capture the contents of each line because your file is formatted pretty nicely, especially due to the comma separation (really useful if none of your separated values contain a comma).

You can pass fscanf a format like you're doing with "%d" to capture an int, "%s" to capture a string (ends at white space, be weary of this when for example trying to find a name like "Annitto Grassis, which would require 2 %s's), etc, from the currently read line of the file. You can be more advanced and use regex patterns to define the contents you want captured as chars, such as "Boatswain", a sequence comprised chars from the sets {A-Z}, {a-z}, and the {"}. You'll want to scan the file until you reach the end (signified by EOF in C) so you can do such and capture the contents of the line and appropriately assign the values to variables like so:

while( fscanf(inputf, "%d,%d,%[\"A-Za-z ],%[\"A-Za-z .]", &term, &id, lastname, firstname) != EOF) {

.... //do something with term, id, lastname, firstname - put them in a student struct

}

For more about regex, Mastering Regex by Jeff Friedl is a good book for learning about the topic.

查看更多
6楼-- · 2019-03-04 20:18

What you have there is a CSV file with quoted strings, and so I would recommend you use a CSV parser (or roll your own) rather than trying to do it all with scanf (since scanf cannot deal with quotes, e.g. commas within quoted strings). A quick Google search turns up libcsv.c which you may be able to use in your project.

查看更多
登录 后发表回答