簡體   English   中英

`C`:從 CVS 文件讀取時字符串未正確更新

[英]`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 我在想,也許因為PGPG-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.

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