位置: 文档库 > C/C++ > C程序输入一个由空格分隔的整数序列的数组

C程序输入一个由空格分隔的整数序列的数组

兮默 上传于 2023-09-20 20:36

《C程序输入一个由空格分隔的整数序列的数组》

在C/C++编程中,处理用户输入的整数序列是常见的需求。尤其是当输入以空格分隔时,如何高效地读取并存储到数组中成为关键问题。本文将详细介绍多种实现方法,分析其优缺点,并提供完整的代码示例,帮助读者掌握这一核心技能。

一、基础方法:使用scanf循环读取

最直观的方法是使用`scanf`函数循环读取整数,直到遇到文件结束符(EOF)或非数字字符。这种方法简单直接,适合初学者理解。

#include 

int main() {
    int arr[100]; // 假设数组最大长度为100
    int count = 0;
    int num;

    printf("请输入空格分隔的整数序列(按Ctrl+D结束输入):\n");
    while (scanf("%d", &num) == 1) {
        arr[count++] = num;
    }

    printf("读取到的数组:\n");
    for (int i = 0; i 

优点:代码简洁,易于理解。
缺点:数组大小固定,无法动态扩展;需要预先知道最大可能输入数量。

二、动态数组实现:使用realloc扩展内存

为了克服固定数组的局限性,可以使用动态内存分配。通过`malloc`和`realloc`函数,根据实际输入数量动态调整数组大小。

#include 
#include 

int main() {
    int *arr = NULL;
    int count = 0;
    int capacity = 0;
    int num;

    printf("请输入空格分隔的整数序列(按Ctrl+D结束输入):\n");
    while (scanf("%d", &num) == 1) {
        // 如果当前数组已满,扩展容量
        if (count >= capacity) {
            capacity = (capacity == 0) ? 1 : capacity * 2;
            int *temp = realloc(arr, capacity * sizeof(int));
            if (temp == NULL) {
                printf("内存分配失败\n");
                free(arr);
                return 1;
            }
            arr = temp;
        }
        arr[count++] = num;
    }

    printf("读取到的数组:\n");
    for (int i = 0; i 

优点:可以处理任意长度的输入序列;内存使用高效。
缺点:代码稍复杂;需要手动管理内存。

三、使用字符串处理:先读取整行再解析

另一种方法是先使用`fgets`读取整行输入,然后使用`strtok`函数分割字符串,最后将每个子字符串转换为整数。

#include 
#include 
#include 

#define MAX_LINE_LENGTH 1000

int main() {
    char line[MAX_LINE_LENGTH];
    int *arr = NULL;
    int count = 0;
    int capacity = 0;

    printf("请输入空格分隔的整数序列:\n");
    if (fgets(line, sizeof(line), stdin) == NULL) {
        printf("读取输入失败\n");
        return 1;
    }

    // 移除可能的换行符
    line[strcspn(line, "\n")] = '\0';

    char *token = strtok(line, " ");
    while (token != NULL) {
        // 扩展数组容量
        if (count >= capacity) {
            capacity = (capacity == 0) ? 1 : capacity * 2;
            int *temp = realloc(arr, capacity * sizeof(int));
            if (temp == NULL) {
                printf("内存分配失败\n");
                free(arr);
                return 1;
            }
            arr = temp;
        }
        arr[count++] = atoi(token);
        token = strtok(NULL, " ");
    }

    printf("读取到的数组:\n");
    for (int i = 0; i 

优点:可以精确控制输入行的长度;适合处理单行输入。
缺点:需要处理字符串转换;多行输入需要额外逻辑。

四、C++中的更优雅实现:使用vector和stringstream

在C++中,可以利用标准库中的`vector`和`stringstream`来更简洁地实现这一功能。

#include 
#include 
#include 
#include 

int main() {
    std::vector arr;
    std::string line;
    int num;

    std::cout > num) {
        arr.push_back(num);
    }

    std::cout 

优点:代码简洁;自动管理内存;支持多行输入(只需修改`getline`调用)。
缺点:需要C++环境;对于纯C项目不适用。

五、错误处理与健壮性增强

在实际应用中,需要添加错误处理机制,确保程序在遇到非法输入时能够优雅地退出或提示用户。

#include 
#include 
#include 

#define INITIAL_CAPACITY 10

int main() {
    int *arr = malloc(INITIAL_CAPACITY * sizeof(int));
    if (arr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    int count = 0;
    int capacity = INITIAL_CAPACITY;
    int num;
    char ch;

    printf("请输入空格分隔的整数序列(按Ctrl+D结束输入):\n");
    while (scanf("%d%c", &num, &ch) == 2) {
        // 检查ch是否是空格、换行或EOF
        if (ch != ' ' && ch != '\n' && ch != EOF) {
            printf("错误:输入包含非空格分隔符 '%c'\n", ch);
            free(arr);
            return 1;
        }

        // 扩展数组
        if (count >= capacity) {
            capacity *= 2;
            int *temp = realloc(arr, capacity * sizeof(int));
            if (temp == NULL) {
                printf("内存分配失败\n");
                free(arr);
                return 1;
            }
            arr = temp;
        }

        arr[count++] = num;

        // 如果ch是换行符或EOF,结束输入
        if (ch == '\n' || ch == EOF) {
            break;
        }
    }

    // 处理可能剩余的输入(如直接按Ctrl+D)
    while (scanf("%d", &num) == 1) {
        if (count >= capacity) {
            capacity *= 2;
            int *temp = realloc(arr, capacity * sizeof(int));
            if (temp == NULL) {
                printf("内存分配失败\n");
                free(arr);
                return 1;
            }
            arr = temp;
        }
        arr[count++] = num;
    }

    printf("读取到的数组:\n");
    for (int i = 0; i 

六、性能分析与优化建议

1. **内存分配策略**:动态数组扩展时采用指数增长(如每次容量翻倍)可以减少realloc调用次数,提高性能。
2. **输入缓冲**:对于大量数据,可以考虑批量读取而不是逐个字符处理。
3. **多线程处理**:在极端情况下,可以考虑将输入处理与后续计算分离到不同线程。
4. **预分配**:如果知道输入的大致范围,可以预先分配足够大的内存。

七、实际应用场景示例

假设需要从用户输入读取一系列数字,计算它们的平均值和标准差:

#include 
#include 
#include 

int main() {
    double *numbers = NULL;
    int count = 0;
    int capacity = 0;
    double num;

    printf("请输入空格分隔的数字序列(按Ctrl+D结束输入):\n");
    while (scanf("%lf", &num) == 1) {
        if (count >= capacity) {
            capacity = (capacity == 0) ? 1 : capacity * 2;
            double *temp = realloc(numbers, capacity * sizeof(double));
            if (temp == NULL) {
                printf("内存分配失败\n");
                free(numbers);
                return 1;
            }
            numbers = temp;
        }
        numbers[count++] = num;
    }

    if (count == 0) {
        printf("没有输入有效数字\n");
        return 0;
    }

    // 计算平均值
    double sum = 0.0;
    for (int i = 0; i 

八、跨平台输入处理注意事项

1. **Windows与Linux/macOS的EOF差异**:Windows下按Ctrl+Z,Unix-like系统下按Ctrl+D。
2. **换行符处理**:不同操作系统使用不同的换行符(\r\n vs \n)。
3. **本地化设置**:某些地区使用逗号作为小数点,需要额外处理。

九、总结与最佳实践

1. **对于C程序**:推荐使用动态数组(malloc/realloc)结合scanf循环读取,平衡灵活性与性能。
2. **对于C++程序**:优先使用vector和stringstream,代码更简洁安全。
3. **错误处理**:始终检查内存分配和输入转换是否成功。
4. **性能考虑**:对于大规模数据,考虑批量读取和预分配策略。

关键词:C语言数组输入、空格分隔、动态内存分配、scanf、fgets、strtok、C++、vector、stringstream、错误处理、性能优化

简介:本文详细介绍了在C/C++中读取由空格分隔的整数序列并存储到数组的多种方法,包括基础scanf循环、动态数组实现、字符串处理、C++的vector方案等,分析了各方法的优缺点,提供了完整的代码示例和错误处理建议,适用于需要处理用户输入整数序列的编程场景。

C/C++相关