C语言练习 输入一行字符,统计其中有多少个单词

要求:输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。

这里我本来想用笨方法判断单词的位置,参考答案之后,发现方法比较精妙。

直接上代码:

#include <stdio.h>

int main()
{
    char c[50];
    gets(c);
    int i=0;
    int word=0,num=0;
    while(c[i]!='\0'){
        if(c[i]==' ')
            word=0;
        else if(word==0){
            word=1;
            num++;

        }
        i++;
    }
    printf("一共有%d个单词",num);

    return 0;
}

这里设置了一个word标志位,在while之中只有一个if语句,读取到的当前字符为空格时,则将word标志为0,仅有下一字符不为空格时,才将word置为1并将单词数+1。

<think>好的,用户现在的问题是关于如何在C语言中将输入字符串数组重新组织成一个二维数组,每个单词一行。首先,我需要理解用户的具体需求。用户提到的是“输入字符串数组重组为一个单词一行的二维数组”,可能是指将包含多个单词字符串分割成单独的单词,每个单词存储在二维数组的一行中。例如,输入字符串是"hello world",输出应该是一个二维数组,其中第一行是"hello",第二行是"world"。 接下来,我需要考虑用户可能的背景。他们可能正在学习C语言,对字符串处理和内存管理不太熟悉。因此,回答需要详细且步骤清晰,同时注意内存分配和释放的问题,避免内存泄漏。此外,用户可能对指针和二维数组的操作不太熟悉,需要解释清楚每一步的逻辑。 用户之前的提问是关于查找数组最大值,现在转向字符串处理,说明他们可能在处理数组和字符串相关的练习题或项目。因此,需要提供可靠的代码示例,并解释关键部分,比如如何分割字符串、动态分配内存等。 首先,C语言中处理字符串数组通常使用字符指针数组,每个指针指向一个字符串。要分割输入字符串,可以使用strtok函数,按空格分割单词。然后,为每个单词分配内存,复制到二维数组中。需要注意的是,二维数组在C中通常是字符数组的数组,但动态分配的话,可能需要使用指针数组,每个元素指向一个动态分配的字符串。 接下来,动态内存分配是关键步骤。需要为每个单词分配足够的内存,并复制内容。同时,要记录单词的数量,并确保最后有一个NULL指针表示结束,方便后续遍历。此外,必须检查内存分配是否成功,避免程序崩溃。 可能的错误点包括:未正确处理多个连续空格,字符串末尾的换行符处理,内存分配不足导致溢出,以及忘记释放内存造成泄漏。因此,在代码示例中需要处理这些情况,比如使用isspace函数判断空白字符,替换换行符为结束符,计算单词长度时加1以容纳'\0',并在最后释放每个单词的内存和指针数组。 用户可能的问题还包括如何处理不同的分隔符,比如逗号或分号,但当前问题可能仅涉及空格。不过,可以提到strtok可以设置分隔符,方便扩展。 最后,总结步骤:读取输入,分割单词,动态分配内存,存储到指针数组,最后输出结果并释放内存。代码示例需要完整,包含必要的头文件,并演示整个流程,包括内存释放,以培养良好的编程习惯。</think>在C语言中,将输入字符串数组重组为一个单词一行的二维数组,需要结合**字符串分割**和**动态内存管理**。以下是分步实现方法: --- ### **实现思路** 1. **输入字符串**:从用户获取一个包含多个单词字符串(例如:`"Hello World C Programming"`) 2. **分割单词**:以空格为分隔符,将字符串切割为多个单词 3. **动态分配内存**:为每个单词分配独立的二维数组行空间 4. **存储结果**:将分割后的单词存入二维数组,每行一个单词 --- ### **完整代码示例** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // 用于处理空白字符 // 功能:分割字符串为单词数组,返回二维指针 char** splitWords(char* input, int* wordCount) { if (input == NULL) return NULL; // 替换末尾换行符(如果从fgets输入) input[strcspn(input, "\n")] = '\0'; // 初步统计单词数量 int count = 0; char* temp = strdup(input); // 避免修改原字符串 char* token = strtok(temp, " "); while (token != NULL) { count++; token = strtok(NULL, " "); } free(temp); *wordCount = count; // 分配指针数组(每行一个单词) char** words = (char**)malloc(count * sizeof(char*)); if (words == NULL) { perror("内存分配失败"); return NULL; } // 第二次遍历填充单词 int index = 0; token = strtok(input, " "); while (token != NULL) { // 跳过连续空格(处理多个空格情况) if (strlen(token) == 0) continue; // 分配内存并复制单词 words[index] = (char*)malloc(strlen(token) + 1); // +1存放'\0' if (words[index] == NULL) { perror("内存分配失败"); return NULL; } strcpy(words[index], token); index++; token = strtok(NULL, " "); } return words; } int main() { char input[100]; printf("请输入字符串(空格分隔单词):"); fgets(input, sizeof(input), stdin); // 安全读取输入 int wordCount = 0; char** words = splitWords(input, &wordCount); // 输出结果 if (words != NULL) { printf("分割后的单词:\n"); for (int i = 0; i < wordCount; i++) { printf("行 %d: %s\n", i+1, words[i]); } // 释放内存 for (int i = 0; i < wordCount; i++) free(words[i]); free(words); } return 0; } ``` --- ### **关键点解析** 1. **两次遍历策略**: - 第一次统计单词数量(避免动态扩容的低效) - 第二次实际分配内存并填充数据 2. **内存管理**: - 使用`strdup`保护原始输入字符串 - 每个单词独立分配内存(`malloc`) - 最终必须手动释放所有内存(`free`) 3. **处理边界情况**: - 输入末尾的换行符(`fgets`会自动添加) - 连续多个空格的情况 - 空输入或无效输入的判断 --- ### **运行示例** ``` 请输入字符串(空格分隔单词):C Language Programming is fun! 分割后的单词: 行 1: C 行 2: Language 行 3: Programming 行 4: is 行 5: fun! ``` --- ### **相关问题扩展** 1. **如何支持多种分隔符(如逗号、分号)?** 修改`strtok`的第二个参数,例如:`strtok(input, " ,;")` 2. **如何避免内存泄漏?** - 确保每个`malloc`都有对应的`free` - 可以使用Valgrind工具检测 3. **如何处理超长输入?** 使用动态增长的缓冲区(如`realloc`)替代固定长度的`char input[100]`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值