You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用strtok与fgets时触发Segmentation Fault问题求助

Fixing Segmentation Fault & Logic Issues in Your Word Count Function

Let's break down why your process_stream function is hitting a segmentation fault and fix the logic errors to get your word counter working correctly.

Critical Bugs in Your Original Code

  1. You discard the first token immediately
    You call strtok(buffer, " \n") to grab the first token, but then immediately overwrite it with token = strtok(NULL, " \n") before processing it. When a line only has one word, this sets token to NULL, and passing a NULL pointer to strcmp (which expects valid C strings) triggers a segmentation fault.

  2. Array index out-of-bounds
    Your loop condition for checking entries is i < entry_count+1, but your entries array only has entry_count elements (indices 0 to entry_count-1). Accessing entries[entry_count] reads memory outside the array, leading to undefined behavior (often a segfault).

  3. Unsafe newline removal
    You directly set buffer[strlen(buffer)-1]='\0' without verifying that character is actually a newline. If fgets returns an empty line or hits EOF right away, strlen(buffer) could be 0, making buffer[-1] an invalid memory access.

  4. No handling for the termination character '.'
    Your requirement states input ends with ., but your code keeps reading until fgets fails (EOF), so it won't stop when the user enters the termination character.

Fixed Version of process_stream

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

// Assuming your WordCountEntry structure looks like this:
typedef struct {
    char* word;
    int counter;
} WordCountEntry;

int process_stream(WordCountEntry entries[], int entry_count) {
    short line_count = 0;
    char buffer[30];
    while (fgets(buffer, sizeof(buffer), stdin)) {
        line_count++;
        
        // Safely remove trailing newline if present
        size_t buf_len = strlen(buffer);
        if (buf_len > 0 && buffer[buf_len - 1] == '\n') {
            buffer[buf_len - 1] = '\0';
        }
        
        // Stop processing when termination character is entered
        if (strcmp(buffer, ".") == 0) {
            break;
        }
        
        char* token = strtok(buffer, " \n");
        while (token != NULL) {
            // Check if current token matches any target word
            for (int i = 0; i < entry_count; i++) {
                if (strcmp(entries[i].word, token) == 0) {
                    entries[i].counter++;
                    break; // Exit early once match is found
                }
            }
            
            // Get the next token
            token = strtok(NULL, " \n");
        }
    }
    return line_count;
}

Key Fixes Explained

  • Process the first token correctly: We now capture the initial token, process it, then fetch the next one in the loop—no more skipping words or passing invalid pointers to strcmp.
  • Valid array bounds: The entry loop uses i < entry_count, ensuring we only access valid indices in the entries array.
  • Safe newline handling: We check if the last character is a newline before modifying it, avoiding invalid memory access for empty lines.
  • Termination check: We compare the input line to . and break the loop immediately, stopping input as required.
  • Early exit in entry loop: Once a matching word is found, we stop checking other entries to save unnecessary iterations.

Testing this with your example input (cat cat nap .) will return the expected result: cat: 2 nap: 1 dog: 0.

内容的提问来源于stack exchange,提问作者flutterbug98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:06:39