我需要为我的Movie struct 获得double值.所以我的任务是从CSV文件中读取(它将被提供)并输出特定的信息,比如这种语言的电影,或者今年上映的电影,或者今年收视率最高的电影.不管怎么说.我遇到的问题是,当我有我的"令牌"时,try 检索它返回的空值.

Main.c个文件:Main.c个文件:

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

struct movie
{
    char *title;
    int year;
    char **lang;
    int numLang; // New variable to store the number of languages
    double ratingValue;
    struct movie *next;
};

/* Parse the curr line which is "," broken and create a movie struct with the data in curr line
*/
struct movie *createMovie(char *currLine)
{
    struct movie *currMovie = malloc(sizeof(struct movie));
    char *ptr;

    // title
    char *token = strtok_r(currLine, ",", &ptr);
    currMovie->title = calloc(strlen(token) + 1, sizeof(char));
    strcpy(currMovie->title, token);

    // year
    token = strtok_r(NULL, ",", &ptr);
    currMovie->year = atoi(token);

    // language
    token = strtok_r(NULL, ",", &ptr);
    token = strtok_r(token, "[];", &ptr);
    currMovie->lang = NULL; // Initialize to NULL
    int numLang = 0; // Initialize numLang
    while (token != NULL)
    {
        currMovie->lang = realloc(currMovie->lang, (numLang + 1) * sizeof(char *));
        currMovie->lang[numLang] = calloc(strlen(token) + 1, sizeof(char));
        strcpy(currMovie->lang[numLang], token);
        numLang++;
        token = strtok_r(NULL, "[];", &ptr);
    }

    // Set numLang for the current movie
    currMovie->numLang = numLang;

    // rating value
    token = strtok_r(NULL, "\n", &ptr);
    if (token != NULL)  // Check if token is not NULL
    {
        // Use sscanf to directly extract the rating value as a float
        if (sscanf(token, "%lf", &currMovie->ratingValue) != 1)
        {
            // Handle the case where the conversion fails
            currMovie->ratingValue = 0.0;
            printf("Token: \"%s\". Invalid or missing rating value. Setting to default (0.0).\n", token);
        }
    }
    else
    {
        // Handle the case where the rating value is missing or invalid
        // For example, set it to a default value or display an error message.
        currMovie->ratingValue = 0.0;
        printf("Token is NULL. Invalid or missing rating value. Setting to default (0.0).\n");
    }

    // Set the next node to NULL
    currMovie->next = NULL;

    return currMovie;
}

/*
* Return linked list of movies by parsing data from each line
*/
struct movie *processFile(char *filePath)
{
    // open file
    FILE *movieFile = fopen(filePath, "r");

    char *currLine = NULL;
    size_t len = 0;
    size_t nread;

    struct movie *head = NULL;
    struct movie *tail = NULL;

    // read file
    while ((nread = getline(&currLine, &len, movieFile)) != -1)
    {
        // Get new movie
        struct movie *newNode = createMovie(currLine);

        // Skip the header line
        if (newNode == NULL)
        {
            continue;
        }

        // id first node
        if (head == NULL)
        {
            // first node in the linked link, Set head and tail to node
            head = newNode;
            tail = newNode;
        }
        else
        {
            tail->next = newNode;
            tail = newNode;
        }
    }
    free(currLine);
    fclose(movieFile);
    return head;
}

.csv文件中的一小部分

Title,Year,Languages,Rating Value
The Incredible Hulk,2008,[English;Portuguese;Spanish],6.8
Sherlock Holmes,2009,[English;French],7.6
Iron Man,2008,[English;Persian;Urdu;Arabic;Hungarian],7.9
Iron Man 2,2010,[English;French;Russian],7.2
Iron Man 3,2013,[English],7.2
Thor: Ragnarok,2017,[English],7.9
The Avengers,2012,[English;Russian;Hindi],8.1
Doctor Strange,2016,[English],7.5
Avengers: Infinity War,2018,[English],8.5
Avengers: Age of Ultron,2015,[English;Korean],7.4
Thor,2011,[English],7
Thor: The Dark World,2013,[English],7

正如您在CSV文件中看到的,在"Rating Value"之后,它移到新行.问题是,当我制作我的电影"列表"时,我需要检索"评级值".我正在编译使用--std=gnu99这是一个系统的要求.我需要从中获得双重价值,如果能得到任何帮助,我将不胜感激.

编辑这是我的输出

flip3 ~/os1 998$ ./movies movies_sample_1.csv
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).
Token is NULL. Invalid or missing rating value. Setting to default (0.0).

1. Show movies released in the specified year
2. Show highest rated movie for each year
3. Show the title and year of release of all movies in a specific language
4. Exit from the program

Enter a choice from 1 to 4: 1
Enter the year for which you want to see movies: 2008
The Incredible Hulk
Iron Man

1. Show movies released in the specified year
2. Show highest rated movie for each year
3. Show the title and year of release of all movies in a specific language
4. Exit from the program

Enter a choice from 1 to 4: 2

Highest rated movie for each year:
0 0.0 Title
2008 0.0 The Incredible Hulk
2009 0.0 Sherlock Holmes
2010 0.0 Iron Man 2
2013 0.0 Iron Man 3
2017 0.0 Thor: Ragnarok
2012 0.0 The Avengers
2016 0.0 Doctor Strange
2018 0.0 Avengers: Infinity War
2015 0.0 Avengers: Age of Ultron
2011 0.0 Thor
2014 0.0 Captain America: The Winter Soldier
2003 0.0 Right on Track

1. Show movies released in the specified year
2. Show highest rated movie for each year
3. Show the title and year of release of all movies in a specific language
4. Exit from the program

Enter a choice from 1 to 4: 3
Enter the language for which you want to see movies: English
2008 The Incredible Hulk
2009 Sherlock Holmes
2008 Iron Man
2010 Iron Man 2
2013 Iron Man 3
2017 Thor: Ragnarok
2012 The Avengers
2016 Doctor Strange
2018 Avengers: Infinity War
2015 Avengers: Age of Ultron
2011 Thor
2013 Thor: The Dark World
2017 Spider-Man: Homecoming
2011 Captain America: The First Avenger
2016 Captain America: Civil War
2015 Ant-Man
2014 Captain America: The Winter Soldier
2018 Mary Queen of Scots
2016 Revolting Rhymes Part One
2017 The Glass Castle
2016 Free Fire
2003 Right on Track
2012 Rise of the Guardians
2012 Anna Karenina

1. Show movies released in the specified year
2. Show highest rated movie for each year
3. Show the title and year of release of all movies in a specific language
4. Exit from the program

Enter a choice from 1 to 4: 4
Exiting the program

推荐答案

代码中存在多个问题:

  • 您可以使用相同的状态指针ptr来解析来自语言字段的令牌和用于封闭行的令牌.您应该使用两个独立的状态指针.这解释了报告的行为.

  • 使用strdup来分配字符串的副本.这只是一种简化.

  • nread的类型应该是ssize_t.

  • 要跳过标题行,只需读取并丢弃文件中的第一行.

以下是修改后的版本:

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

struct movie {
    char *title;
    int year;
    char **lang;
    int numLang; // New variable to store the number of languages
    double ratingValue;
    struct movie *next;
};

/* Parse the curr line which is "," broken and create a movie struct with the data in curr line
 */
struct movie *createMovie(char *currLine)
{
    struct movie *currMovie = malloc(sizeof(struct movie));
    if (!currMovie)
        return NULL;

    char *ptr;
    // title
    char *token = strtok_r(currLine, ",", &ptr);
    currMovie->title = strdup(token ? token : "");

    // year
    token = strtok_r(NULL, ",", &ptr);
    currMovie->year = token ? atoi(token) : 0;

    // language
    currMovie->lang = NULL;
    currMovie->numLang = 0;

    token = strtok_r(NULL, ",", &ptr);
    if (token) {
        int numLang = 0;
        char *ptr1;
        token = strtok_r(token, "[];", &ptr1);
        while (token != NULL) {
            currMovie->lang = realloc(currMovie->lang, (numLang + 1) * sizeof(char *));
            if (currMovie->lang == NULL)
                break;
            currMovie->lang[numLang] = strdup(token);
            currMovie->numLang++;
            numLang++;
            token = strtok_r(NULL, "[];", &ptr1);
        }
    }

    // rating value
    token = strtok_r(NULL, "\n", &ptr);
    if (token) {
        if (sscanf(token, "%lf", &currMovie->ratingValue) != 1) {
            currMovie->ratingValue = 0.0;
            printf("Token: \"%s\". Invalid rating value. Setting to default (0.0).\n", token);
        }
    } else {
        currMovie->ratingValue = 0.0;
        printf("Missing rating value. Setting to default (0.0).\n");
    }
    currMovie->next = NULL;
    return currMovie;
}

/*
 * Return linked list of movies by parsing data from each line
 */
struct movie *processFile(const char *filePath)
{
    // open file
    FILE *movieFile = fopen(filePath, "r");
    if (movieFile == NULL) {
        fprintf(stderr, "cannot open %s: %s\n", filePath, strerror(errno));
        return NULL;
    }

    char *currLine = NULL;
    size_t len = 0;
    ssize_t nread;

    struct movie *head = NULL;
    struct movie *tail = NULL;

    // skip the header line
    getline(&currLine, &len, movieFile);

    // read file
    while ((nread = getline(&currLine, &len, movieFile)) >= 0)
    {
        // Get new movie
        struct movie *newNode = createMovie(currLine);

        if (newNode == NULL)
        {
            continue;
        }

        // id first node
        if (head == NULL)
        {
            // first node in the linked link, Set head and tail to node
            head = newNode;
            tail = newNode;
        }
        else
        {
            tail->next = newNode;
            tail = newNode;
        }
    }
    free(currLine);
    fclose(movieFile);
    return head;
}

C++相关问答推荐

如何通过Zephyr(Devicetree)在PR Pico上设置UTE 1?

无效使用未定义类型'structsquare'?

在#include中使用C宏变量

C由四个8位整数组成无符号32位整数

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

限制不同类型的限定符

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

函数的限制限定指针参数允许优化调用方函数吗?

我的C函数起作用了,但我不确定为什么

使用nmake for程序比Hello World稍微复杂一些

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

Fprintf正在写入多个 struct 成员,并且数据过剩

用于计算位数和的递归C函数

OMP并行嵌套循环

C:面筋蛋白';为什么不刷新窗口?

分配给静态变量和动态变量的位置之间有区别吗?

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

%g浮点表示的最大字符串长度是多少?

如何修复数组数据与列标题未对齐的问题?

文件指针引起的C程序分段错误