[英]`C`: String not being updated properly when reading from a CVS file
我得到了一個電影放映時間信息的文本文件。 我必須以干凈的方式格式化信息。 現在我只是想將所有行的信息保存到字符串中。 但是,當獲取電影的評級時,數組不會正確保存評級。
這是主要代碼。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const int MAX_TITLE_CHARS = 44; // Maximum length of movie titles
const int LINE_LIMIT = 100; // Maximum length of each line in the text file
char line[LINE_LIMIT];
char inputFileName[25];
FILE *file;
file = fopen("D:\\movies.txt", "r");
char currentLine[LINE_LIMIT];
char movieTitle[MAX_TITLE_CHARS];
char movieTime[10];
char movieRating[10];
fgets(currentLine, LINE_LIMIT, file); // Get first file
while(!feof(file)){
sscanf(currentLine, "%[^,],%44[^,],%s", movieTime, movieTitle, movieRating);
printf("%s\n", movieRating);
fgets(currentLine, LINE_LIMIT, file); // Get next file
}
return 0;
}
這是 CVS 文件
16:40,Wonders of the World,G
20:00,Wonders of the World,G
19:00,Journey to Space ,PG-13
12:45,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
15:00,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
19:30,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
10:00,Adventure of Lewis and Clark,PG-13
14:30,Adventure of Lewis and Clark,PG-13
19:00,Halloween,R
這打印出來
G
G
PG-13
PG-13
PG-13
PG-13
PG-13
PG-13
R
我需要它是
G
G
PG-13
PG
PG
PG
PG-13
PG-13
R
我使用 Eclipse 並且在調試器中時,我看到當它遇到第一個PG-13
時,它根本不會更新,直到R
。 我在想,也許因為PG
和PG-13
有相同的兩個起始字符,所以它可能會混淆嗎? 我不確定。 任何幫助表示贊賞。
您的字符串“Buffalo Bill...”超過 44 個字符。 因此 sccanf 語句讀取到該限制,然后查找字符串中不存在的“,”並退出 44 個字符。
因為你的新movieRating
沒有被設置,它只是打印以前的值。
提示:如果您正在尋找解決方法,您可以使用類似strsep()
的方法來解析您的字符串。 您也可以只增加電影標題的大小。
您正在使用以下行轉換行:
sscanf(currentLine, "%[^,],%44[^,],%s", movieTime, movieTitle, movieRating);
function 會將一個字符串讀入 movietTime,直到輸入中出現“,”,然后它會讀取另一個字符串,直到出現“,”或讀取 44 個字符。 此行為在sscanf
的手冊中進行了解釋:
...
An optional decimal integer which specifies the maximum field width.
Reading of characters stops either when this maximum is reached or when
a nonmatching character is found, whichever happens first...
具有 PG 評級的行具有 62 個字符的標題。 因此,它不會讀取整個標題,也不會找到逗號。 要解決此問題,您可以將 MAX_TITLE_CHARS 設置為更大的值或使用%m
修飾符讓sscanf
為您動態分配字符串。
OP 代碼具有未定義的行為(UB),因為movieTitle[]
僅足夠大以容納 43 個字符 + 終止字符 null ,並且 OP 使用"%44[^,]"
而不是正確的寬度限制 43。
const int MAX_TITLE_CHARS = 44; // Maximum length of movie
...
char movieTitle[MAX_TITLE_CHARS];
此 UB 之后還有其他問題。
占行的'\n'
和'\0'
組成一個字符串。
永遠不要使用while(feof(...))
。
測試sscanf()
結果。
以precision限制打印的標題寬度。
const int LINE_LIMIT = 100; // Maximum length of each line in the text file
char line[LINE_LIMIT + 2 /* room for \n and \0 */];
while (fgets(currentLine, sizeof currentLine, file)) {
// Either use a _width limit_ with `"%s"`, `"%[]"` or use a worse case size.
char movieTime[10 + 1]; // 10 characters + \0
char movieTitle[sizeof currentLine];
char movieRating[sizeof currentLine];
// Examples:
// Use a 10 width limit for the 11 char movieTime
// Others: use a worst case size.
if (sscanf(currentLine, " %10[^,], %[^,], %[^\n]",
movieTime, movieTitle, movieRating) != 3) {
fprintf(stderr, "Failed to parse <%s>\n", currentLine);
break;
}
// Maximum length of movie titles _to print_
const int MAX_TITLE_CHARS = 44;
printf("Title: %-.*s\n", MAX_TITLE_CHARS, movieTitle);
printf("Rating: %s\n", movieRating);
}
請注意,如果長度包含結尾'\n'
,則“每行的最大長度”不清楚。 在 C 庫中,一行包含'\n'
。
文本 stream 是一個有序的字符序列,由lines組成,每行由零個或多個字符加上一個終止換行符組成。 最后一行是否需要終止換行符是實現定義的。 C17dr § 7.21.2 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.