[英]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'
// 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.