簡體   English   中英

從文件讀取意外的 output

[英]Unexpected output reading from a file

我有一個要閱讀的文本文件。 該文件具有以下內容:

Asdsf adsfsd
54
asdfa adwfasd
12
asdf adf 
545
asdf asdfasfd
3243
adfasf asdfasdf
324324
asfda asdfasdf
3124
adfa asdfas
432
asdf ad

和我的代碼:

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


struct Element {
    int edad;
    char name[50];
};

int main() {
    struct Element aux;
    FILE* fitxer;
    fopen_s(&fitxer, "Text.txt", "r");
    if (fitxer != NULL) {
        while (!feof(fitxer)) {
            fgets(aux.name, 50, fitxer);
            aux.name[strlen(aux.name) - 1] = '\0';
            int ret = fscanf_s(fitxer, "%i", &aux.edad);
            char endl;
            fscanf_s(fitxer, "%c", &endl);
            printf("%d %s \n", aux.edad, aux.name);
        }
        fclose(fitxer);
    }
    else {
        printf("Error: File not found.");
    }    
}

我之前遇到過問題,因為我不知道f_scanf不帶結束符。 現在的問題是文件中有一些字符串被截斷了。 Output:

54 Asdsf adsfsd
12 asdfa adwfasd
545 asdf adf
3243 asdf asdfasfd
324324 adfasf asdfasdf
3124 asfda asdfasdf
432 adfa asdfas
432 asdf a

例如,在這個例子中,最后一個字母被切掉了。 我懷疑它與轉換為字符串有關,添加了'\0'字符,但我找不到錯誤。

另外我想問一下是否有辦法讓它更優雅。

aux.name[strlen(aux.name) - 1] = '\0';

您擺脫了fgets的一個眾所周知的行為:它將整行存儲到 output 緩沖區中,包括'\n'字符。

但是如果那個角色不存在呢? 你會砍掉最后一個字符。

這正是您閱讀文件的最后一行時發生的情況。 由於沒有尾隨'\n'字符,因此fgets會在到達文件末尾時立即停止。

要修復它,只需檢查要替換的字符是否是預期的。

像這樣的東西:

size_t len = strlen(aux.name);

if(len > 0 && aux.name[len - 1] == '\n')
    aux.name[len - 1] = '\0';

檢查len > 0避免了長度為 0 的字符串的未定義行為(如果該行的第一個字符是'\0' ,則會發生這種情況)。

至少3個問題:

錯誤的文件結尾測試,避免幻數

參考

//while (!feof(fitxer)) {
//    fgets(aux.name, 50, fitxer);
while (fgets(aux.name, sizeof aux.name, fitxer)) {

fscanf_s(fitxer, "%c", &endl); 缺少一個增強。

如果感興趣,請研究fscanf_s() ,或者更好的是,只需使用fgets()進行輸入。

終止潛在試用的錯誤代碼'\n'

替代品: 1 2

// aux.name[strlen(aux.name) - 1] = '\0';
aux.name[strcspn(aux.name, "\n")] = '\0';
aux.name[strlen(aux.name) - 1] = '\0';

這行從您使用fgets讀取的字符串中刪除了最后一個字符。 對於大多數行,該字符是行尾的\n 但我假設你的最后一行最后沒有換行符。 所以你砍掉實際的最后一個字符。

要解決此問題,您應該僅在最后一個字符等於'\n'時將其截斷。

PS:您對fscanf_s的最后一次調用失敗,您最終打印出與上一行相同的數字。 我不確定這是否是故意的。

PPS:如果您對fscanf_s的最后一次調用沒有失敗,則您的 while 循環將循環一次,因為feof僅在先前的讀取因文件結尾而失敗時才返回 true。 因此,您可能不想使用feof ,而是直接檢查您的讀取操作是否失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM