在c编程中从文件中读取字符串char和int

在c编程中从文件中读取字符串char和int,c,file-io,C,File Io,我正在尝试读取此文件,并在c编程的变量中保存最高级别的详细信息。 我的代码如下,但不完整 student.dat file ---------------- Stu:1 abc ($) - 55 in following order (Stu: %d %s (%c) - %d) Stu:2 pqr (^) - 82 正如用户3386109已经暗示的那样:格式字符串“Stu:%d%s(%c)-%d”应该这样做。实际上没有,你也需要添加换行符 int main(){ int num,

我正在尝试读取此文件,并在c编程的变量中保存最高级别的详细信息。 我的代码如下,但不完整

student.dat file
----------------
Stu:1 abc ($) - 55  in following order  (Stu: %d %s (%c) - %d)
Stu:2 pqr (^) - 82

正如用户3386109已经暗示的那样:格式字符串
“Stu:%d%s(%c)-%d”
应该这样做。实际上没有,你也需要添加换行符

int main(){

    int num, grade;
    char id, name[35];

    FILE *fp = NULL;

    fp = fopen("student.dat", "r");
    if (fp != NULL) {

        while ((fp != '\n') && (fp != EOF)) {

            fscanf(fp, "%d %s %c %d", &num, name, id, &grade);
            printf("Student Num: %d", num);
            printf("Student Name: %s", name);
            printf("Student id: %c", id);
            printf("Student grade: %d", grade);         

        }

        fclose(fp);
    }else {
        printf("Failed to open file\n");
    }
}
(是的,我敢肯定,这一代人可以做得更简单;-)

输入的前10行(新行是
\n
无处不在):


(文件以新行结尾
\n
!)

正如用户3386109已经暗示的那样:格式字符串
“Stu:%d%s(%c)-%d”应该可以这样做。实际上没有,你也需要添加换行符

int main(){

    int num, grade;
    char id, name[35];

    FILE *fp = NULL;

    fp = fopen("student.dat", "r");
    if (fp != NULL) {

        while ((fp != '\n') && (fp != EOF)) {

            fscanf(fp, "%d %s %c %d", &num, name, id, &grade);
            printf("Student Num: %d", num);
            printf("Student Name: %s", name);
            printf("Student id: %c", id);
            printf("Student grade: %d", grade);         

        }

        fclose(fp);
    }else {
        printf("Failed to open file\n");
    }
}
(是的,我敢肯定,这一代人可以做得更简单;-)

输入的前10行(新行是
\n
无处不在):


(文件以新行结尾
\n
!)

在C中,有两种主要方法可以读取面向行的输入,然后解析为单个值(实际上是3,但我们现在将忽略在字符串中遍历一对指针)

首选方式是使用面向行的输入函数,如
fgets
或POSIX
getline
将整行读取到缓冲区,然后使用
sscanf
解析缓冲区,这可以比调用
fscanf
更灵活

尽管如此,在这里,您似乎致力于使用
fscanf
。成功使用
fscanf
的关键是提供一个格式字符串,用于说明要读取的行中的所有字符,或者制作格式字符串以利用各个格式说明符的属性来完成相同的任务(例如
%s
(以及您的数字转换)将跳过前导空格,使您能够控制如何处理输入缓冲区(文件或
stdin
)中的行尾,从而成为后续调用
fscanf
时可用的下一个字符,如果处理不当,将对您的读取例程造成影响

另一个强制步骤是验证在每次读取期间是否成功完成了所有指定的转换。您可以通过检查
fscanf
返回值来完成此操作,该值是匹配计数(发生的成功转换数的计数)。如果不进行检查,您就无法确信您的值实际上保存了您认为它们保存的数据

综合起来,使用输入文件,并将要打开的文件名作为程序的第一个参数(如果没有给出文件名,则默认在
stdin
上读取),可以执行以下操作:

Stu:1 qim (+) - 13
Stu:2 EcF (L) - 61
Stu:3 Ko1 (Q) - 50
Stu:4 Ve7 (,) - 23
Stu:5 NiX (;) - 28
Stu:6 4O8 (C) - 73
Stu:7 00m (]) - 79
Stu:8 uiw (C) - 45
Stu:9 47k (X) - 80
Stu:10 MmJ (A) - 38
#包括
int main(int argc,字符**argv){
int num=0,grade=0,max=0;/*初始化所有变量*/
字符id=0,名称[35];
const char*fmt=“Stu:%d%s(%c)-%d”/*给定格式字符串*/
FILE*fp=NULL;
如果(!(fp=argc>1?fopen(argv[1],“r”):stdin)){
fprintf(stderr,“错误:文件打开失败“%s”。\n”,argv[1]);
返回1;
}
/*阅读每行并验证4次成功转换*/
while(fscanf(fp、fmt、num、name、id和grade)==4){
如果(坡度>最大值)最大值=坡度;
printf(“学生人数:%d姓名:%-12s id:%c成绩:%d\n”,
编号、名称、id、等级);
}
printf(“\n最高等级:%d\n\n”,最大值);
如果(fp!=stdin)fclose(fp);
返回0;
}
示例使用/输出

#include <stdio.h>

int main (int argc, char **argv) {

    int num =0, grade = 0, max = 0;         /* initialize all variables */
    char id = 0, name[35];
    const char *fmt = " Stu:%d %s (%c) - %d";  /* given format string */
    FILE *fp = NULL;

    if (!(fp = argc > 1 ? fopen (argv[1], "r") : stdin)) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }
    /* read each line and validate 4 successful conversions */
    while (fscanf (fp, fmt, &num, name, &id, &grade) == 4) {
        if (grade > max) max = grade;
        printf ("Student Num: %d  Name: %-12s  id: %c  grade: %d\n",
                num, name, id, grade);         
    }
    printf ("\n highest grade : %d\n\n", max);

    if (fp != stdin) fclose (fp);

    return 0;
}

$./bin/stdntread在C中,有两种主要方法可以读取面向行的输入,然后解析为单个值(实际上是3种,但现在我们将忽略在字符串中遍历一对指针)

首选方式是使用面向行的输入函数,如
fgets
或POSIX
getline
将整行读取到缓冲区,然后使用
sscanf
解析缓冲区,这可以比调用
fscanf
更灵活

尽管如此,您似乎仍然致力于在此处使用
fscanf
。成功使用
fscanf
的关键是提供一个格式字符串,该字符串可以解释要读取的行中的所有字符,或者精心设计格式字符串,以利用各个格式说明符的属性来完成相同的任务(例如,
%s
(以及您的数字转换)将跳过前导空格,从而使您能够控制处理可能留在输入缓冲区中的行尾(文件或
stdin
,因此是后续调用
fscanf
时可用的下一个字符,如果处理不当,将对读取例程造成影响

另一个强制步骤是验证在每次读取期间是否成功完成了所有指定的转换。您可以通过检查
fscanf
返回值来完成此操作,该值是匹配计数(发生的成功转换数的计数)。如果不进行检查,您就无法确信您的值实际上保存了您认为它们保存的数据

综合起来,使用输入文件,并将要打开的文件名作为程序的第一个参数(如果没有给出文件名,则默认在
stdin
上读取),可以执行以下操作:

Stu:1 qim (+) - 13
Stu:2 EcF (L) - 61
Stu:3 Ko1 (Q) - 50
Stu:4 Ve7 (,) - 23
Stu:5 NiX (;) - 28
Stu:6 4O8 (C) - 73
Stu:7 00m (]) - 79
Stu:8 uiw (C) - 45
Stu:9 47k (X) - 80
Stu:10 MmJ (A) - 38
#包括
int main(int argc,字符**argv){
int num=0,grade=0,max=0;/*初始化所有变量*/
字符id=0,名称[35];
const char*fmt=“Stu:%d%s(%c)-%d”/*给定格式字符串*/
FILE*fp=NULL;
如果(!(fp=argc>1?fopen(argv[1],“r”):stdin)){
fprintf(stderr,“错误:文件打开失败“%s”。\n”,argv[1]);
返回1;
}
/*阅读每行并验证4次成功转换*/
而(fscanf)(fp,f)
$ ./bin/stdntread <dat/stdntread.dat
Student Num: 1  Name: abc           id: $  grade: 55
Student Num: 2  Name: pqr           id: ^  grade: 82

 highest grade : 82
 int num, grade;
    char id, name[35];

FILE *fp = NULL;

fp = fopen("student.dat", "r");
if (fp != NULL) {

    int ret;
    while((ret = fscanf(fp, "%d %s %c %d", &num, name, &id, &grade))!=EOF)
    {    printf(" Student Num: %d", num);
        printf(" Student Name: %s", name);
        printf(" Student id: %c", id);
        printf(" Student grade: %d\n", grade);
    }

    fclose(fp);
}else {
    printf("Failed to open file\n");
}