繁体   English   中英

如何让我的 C 代码从 C 文件中读取并显示多行?

[英]How can I have my C code read and display multiple lines from a C file?

我正在尽力让代码从文本文件中读取多行文本。 文本文件包含的示例 output 如下所示(第一个是 studentID,第二个是 gpa,第三个是缩写):

12345 3.50000 aj
34286 4.10000 be

我只需要屏幕向我显示学生 ID 和 gpa。 我已经让它显示第一行代码,但不是代码的 rest。 我的代码如下:

void displayStudentGpas(FILE* inFile){
    int studentID;
    double gpa;
    char pipe = '|';
    
    while(fscanf(inFile, "%d %lf", &studentID, &gpa) == 2){
        printf("||%11d%4c%11.2lf%8c| \n", studentID, pipe, gpa, pipe);
        printf("||--------------|---------------------|| \n);
    }
}

我将不胜感激您能给我的任何帮助...谢谢!

在 C 中,每当您需要一次读取一行时,您可以使用面向行的输入 function ,如fgets()或 POSIX getline() 这样您就可以使用整行输入,并且不会留下部分行未读。

在您的情况下,您尝试使用带有"%d %lf"格式字符串的格式化输入function fscanf() (但干得好。在检查退货时:)。 当您尝试阅读时会发生什么:

12345 3.50000 aj

是从输入缓冲区中留下"aj\n"的行中读取12345 3.50000 - 未读。 然后在您的下一次迭代中,您尝试使用"%d %lf"再次读取并发生匹配失败,因为"aj"不是有效的 integer输入。

匹配失败发生时,字符提取停止,输入缓冲区中的"aj"再次未读。 但是,由于您正确地检查了返回并在成功读取这两个值的情况下设置了读取循环 - 您的循环终止,而不是进入无限循环,试图一遍又一遍地读取"aj"

注意:您的第三类输入函数是面向字符的函数,例如getchar()fgetc()getc()

解决方案很简单。 使用fgets()和足够大的缓冲区(不要忽略大小)来读取整行,然后使用sscnaf()来解析缓冲区中的所有(或仅前两个)值,并使用 output 解析 studentID 和 gpa。 你可以做:

#include <stdio.h>

#define MAXC 1024       /* if you need a constant, #define one (or more) */
#define MAXI 8

int main (int argc, char **argv) {
    
    char buf[MAXC];     /* buffer to hold entire line */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    
    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }
    
    while (fgets (buf, MAXC, fp)) {                     /* read each line */
        int id;         /* ID */
        double gpa;     /* GPA */
        if (sscanf (buf, "%d %lf", &id, &gpa) == 2)     /* parse id & gpa from buf */
            printf ("%-8d %5.1f\n", id, gpa);           /* on success -- output */
    }
    
    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);
}

注意:程序将从作为第一个参数传递给程序的文件名读取,或者如果没有提供参数,则默认从标准输入读取——许多stdin实用程序的方式)

如果您使用的是 memory 受限的嵌入式系统,您可以相应地调整MAXC (比如32是一个很好的二的幂,并且仍然提供 15 个字符的边距)

示例使用/输出

只需在stdin中传递您的示例输入,您将收到:

$ cat << eof | ./bin/studentidgpa
> 12345 3.50000 aj
> 34286 4.10000 be
> eof
12345      3.5
34286      4.1

要从文件名中读取值,您可以使用:

$ ./bin/studentidgpa filetoread

或者,如果您愿意,您可以在stdin上重定向filetoread ,例如

$ ./bin/studentidgpa < filetoread

如果您有其他问题,请查看并告诉我。

这将是我在 cpp 中解决您的问题的方法,请告诉我是否应该为您将其转换为 c:

#define studentCount 2
 //change if you have more than 2 students
void printStudents(std::string FILENAME) {
    std::ifstream file(FILENAME);

    int studentID[studentCount];
    double gpa[studentCount];
    std::string name[studentCount];

    std::string line; //tmp variable to store a line
    if (file.is_open()) {
        int i = 0;//Counter to keep track of the current student
        while (getline(file, line))
        {
            int a = 0;//Counter to keep track of the current student data
            std::stringstream ss(line);
            while (getline(ss, line, ' ')) { //Split line by ' ' and store in line

                switch (a)
                {
                case 0:
                    studentID[i] = std::stoi(line); //Convert string to int
                    break;
                case 1:
                    gpa[i] = std::stod(line); //Convert string to double
                    break;
                case 2:
                    name[i] = line; //Nothing :(
                    break;
                default:
                    break;
                }
                a++;
            }
            i++;
        }
    }

    for (int i = 0; i < studentCount; i++) {
        std::cout << "ID: " << studentID[i] << " | gpa:" << gpa[i] << " | Name: " << name[i] << "\n";
        std::cout << "||--------------|---------------------|| \n";
    }
}


int main()
{
    std::string FILENAME = "test.txt";

    printStudents(FILENAME);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM