C语言存储输入单词长度的数组赋值失败,打印显示为空
核心问题排查
你观察到的数组值丢失、连初始0都不存在的现象,本质是非法内存越界写入破坏栈内存,结合代码逻辑一共有4个明确错误:
- 负下标越界写入
程序启动时nw初始值为0,如果输入内容以空格、换行、制表符这类分隔符开头,代码在碰到第一个字符时就会进入分隔符处理分支,执行n_words[nw - 1] = nc,也就是向n_words[-1]的内存位置写值。这个位置不属于你初始化的n_words数组的合法范围,这类越界写会直接覆盖栈上相邻的内存数据,也就是你之前给n_words所有元素初始化的0值。 - 连续分隔符覆盖有效数组值
代码碰到任意分隔符时都会无条件执行长度赋值,没有校验当前是否真的处于单词结束状态。比如两个单词之间存在2个连续空格时,第一个空格会正常存储前一个单词的长度,第二个空格触发判断时,state已经是OUT,nc被重置为0,代码会再次执行赋值操作,把之前存在数组里的有效长度覆盖为0。 - 末尾无分隔符的单词不会被存入数组
存储单词长度的逻辑完全绑定在“碰到分隔符”的触发条件上,如果输入内容以单词结尾(没有末尾空格/换行就直接触发EOF),最后一个单词的长度永远不会被写入数组。 - 超出容量时的二次越界
你定义的n_words数组最多存储10个单词的长度,如果输入的单词数超过10个,nw会持续累加,写入时的下标nw-1会超过数组最大下标9,再次触发越界写,进一步破坏内存数据。
修正后的可运行代码
#include <stdio.h> #define OUT 0 #define IN 1 #define MAX_WORDS 10 int main() { int n_words[MAX_WORDS]; int c, nw, nc, state; state = OUT; nw = nc = 0; for(int i = 0; i < MAX_WORDS; ++i){ n_words[i] = 0; } while((c = getchar()) != EOF){ if (c == ' ' || c == '\n' || c == '\t'){ // 仅从单词状态切换到分隔符时,才代表刚结束一个有效单词 if (state == IN){ // 校验下标范围,防止越界 if (nw <= MAX_WORDS){ n_words[nw - 1] = nc; printf("第 %d 个单词长度为 %d\n", nw - 1, nc); } nc = 0; state = OUT; } } else if(state == OUT){ state = IN; ++nw; // 单词数超容量时给出提示,不执行越界写入 if (nw > MAX_WORDS) { printf("单词数超过数组可存储上限,超出部分将被丢弃\n"); } } // 仅在单词状态下累加字符计数,避免把分隔符算入长度 if (state == IN) { ++nc; } } // 处理输入结束时,末尾没有分隔符的最后一个单词 if (state == IN && nw <= MAX_WORDS) { n_words[nw - 1] = nc; printf("第 %d 个单词长度为 %d\n", nw - 1, nc); } for(int i = 0; i < MAX_WORDS; i++){ printf("%d, ", n_words[i]); } return 0; }
内容的提问来源于stack exchange,提问作者Bididi
相关产品推荐
相关产品推荐

