簡體   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