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

咨询:如何实现C语言中的字符串提取与插入函数

Alright, let's tackle this problem step by step. I'll walk you through implementing the two functions you need, following the exact rules you laid out for reading strings from a file stream into your My_string type.

Implementing My_string Stream Reading Functions

First, let's define a common My_string structure to work with (since you didn't provide one, this is a standard implementation that aligns with your requirements):

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

// Core My_string structure
typedef struct {
    char* data;       // Buffer holding the string (null-terminated)
    size_t length;    // Current number of characters (excluding null terminator)
    size_t capacity;  // Total allocated space (includes room for null terminator)
} My_string;

// Handle type for My_string objects
typedef My_string* My_string_handle;

Now we'll build two functions: a helper to manage dynamic capacity growth, and the main function to handle the stream reading logic with your specified rules.

1. Helper Function: my_string_reserve (Capacity Growth)

This function ensures your My_string has enough space to add new characters, growing the buffer as needed. It's critical for fulfilling the "capacity grows on demand" requirement.

// Precondition: hMy_string is a valid My_string handle
// Postcondition: hMy_string's capacity is at least new_capacity; existing data is preserved
int my_string_reserve(My_string_handle hMy_string, size_t new_capacity) {
    if (!hMy_string) return -1; // Fail if handle is invalid

    // No need to resize if we already have enough space
    if (new_capacity <= hMy_string->capacity) {
        return 0;
    }

    // Reallocate buffer (add 1 extra byte for the null terminator)
    char* new_data = realloc(hMy_string->data, new_capacity + 1);
    if (!new_data) {
        perror("Failed to expand string buffer");
        return -1;
    }

    hMy_string->data = new_data;
    hMy_string->capacity = new_capacity;
    return 0;
}

This function implements the core logic: skipping leading whitespace, reading characters until a stop condition, and ensuring the string grows as needed.

// Precondition: hMy_string is a valid My_string handle; fp is a valid open file stream
// Postcondition: hMy_string contains the next string from fp (per rules), or is empty if EOF is reached
int my_string_read_next_from_stream(My_string_handle hMy_string, FILE* fp) {
    if (!hMy_string || !fp) return -1;

    // Reset the string to empty before starting a new read
    hMy_string->length = 0;
    if (hMy_string->data) {
        hMy_string->data[0] = '\0';
    }

    // Step 1: Skip all leading whitespace characters
    int c;
    while ((c = fgetc(fp)) != EOF && isspace(c)) {
        // Just consume whitespace—do nothing else
    }

    // If we hit EOF after skipping whitespace, return early
    if (c == EOF) {
        return 0;
    }

    // Initialize capacity if the string was empty
    if (hMy_string->capacity == 0) {
        if (my_string_reserve(hMy_string, 16) != 0) { // Start with 16-char buffer (adjustable)
            return -1;
        }
    }

    // Step 2: Read characters until stop condition (whitespace or EOF)
    do {
        // Expand capacity if we're running out of space (double capacity each time for efficiency)
        if (hMy_string->length >= hMy_string->capacity) {
            if (my_string_reserve(hMy_string, hMy_string->capacity * 2) != 0) {
                return -1;
            }
        }

        // Add the current character to the string
        hMy_string->data[hMy_string->length++] = (char)c;
        hMy_string->data[hMy_string->length] = '\0'; // Maintain null termination

        // Read the next character
        c = fgetc(fp);
    } while (c != EOF && !isspace(c));

    // Put the stop character back into the stream (optional, useful for sequential reads)
    if (c != EOF) {
        ungetc(c, fp);
    }

    return 0;
}

Key Details to Note:

  • Leading Whitespace: Uses isspace() from <ctype.h> to skip all standard whitespace (spaces, tabs, newlines, etc.) before reading the actual string content.
  • Capacity Growth: We double the buffer size each time we need more space—this gives amortized constant time complexity for each character added, making the function efficient even for large strings.
  • Stop Condition: Currently stops at whitespace or EOF. If you need a different stop condition (like a specific delimiter, e.g., comma or semicolon), just modify the while loop condition (e.g., while (c != EOF && c != ',')).
  • Null Termination: The string is always kept null-terminated, so it works seamlessly with standard C string functions like printf() or strlen().

Example Usage:

int main() {
    My_string str = {NULL, 0, 0};
    My_string_handle hStr = &str;

    FILE* fp = fopen("input.txt", "r");
    if (!fp) {
        perror("Failed to open input file");
        return 1;
    }

    // Read strings from the file until EOF
    while (my_string_read_next_from_stream(hStr, fp) == 0 && hStr->length > 0) {
        printf("Read string: '%s'\n", hStr->data);
    }

    // Cleanup resources
    free(str.data);
    fclose(fp);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:25:14