数组作为函数参数范围问题

Arthuel 2010-05-19 05:29:36
新学编程,
遇到了一个问题:红色部分关于i<lim-1是为什么不明白,是否可以i<=lim-1,
同时,当我删除这部分以后,输出效果也很奇怪,最多可以输出12个字符;有时会输出错误需关闭,有时会输出烫烫烫烫烫烫

#include<stdio.h>

#define MAXLINE 10 /* 允许输入的最大长度 */

int getline(char line[], int maxline);
void copy(char to[], char from[]);

/* 打印最长的输入行 */
int main(void)
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];

max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max){
max = len;
copy(longest, line);
}
if (max > 0)
printf("%s", longest);
return 0;
}


/* getline函数: 将一行读入大到s中并返回其长度 */
int getline(char s[], int lim)
{
int c, i;

for (i=0; i<lim-1 (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}

/* copy函数: 将from复制到to; 这里假定to 足够大 */
void copy(char to[], char from[])
{
int i;

i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}

此外,曾经遇到过一个题目,解答时有一句话
This solution, which I wrote myself, is the sadly discredited Cat 0 answer which has found a new lease of life in Category 1.
不明白category 0 1是什么,能不能也帮忙解答一下~谢谢
...全文
124 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Arthuel 2010-05-20
  • 打赏
  • 举报
回复
谢谢大家,我明白了一些,但还是有点不懂:
#4:line[]s[]from[]应该是一个数组,都是输入赋值的吧,但是不知为什么我也不能输出line,空的
#6:好像category 0 比1 好一点,这人写这句话好像挺惭愧自己cate 1了这样的,而两个程序的不同之处就在于一个用switch--(1),一个用if--(0);当时switch还没讲过,但不知道和这个有没有关系。
关于越界,我现在已经知道了在数组最后一个加\0这样处理会更安全,
但是如果不加的话会怎么样,不懂为什么会输出这种结果
数组的内存分配是怎么样的,最后都自动添加\0,那int a[X];a[X] == 0?
像原来的程序,如果改成i < lim;如果输入时10以上,那就没有空格存储\0,这样为什么定义的copy函数还能结束;
cattycat 2010-05-19
  • 打赏
  • 举报
回复
MAXLINE 10
长度只有10啊,明显越界了。
lrsunny1 2010-05-19
  • 打赏
  • 举报
回复
getchar()函数不会添'\0'结束符,而printf(“%s”,line)中%s需要'\0'作为字符串结束。其实getline()函数的作用就是把输入的字符保存为字符串。
category 0 1应该是他提供答案的版本吧,呵呵,愚见愚见
huanmie_09 2010-05-19
  • 打赏
  • 举报
回复
问题主要出在这个函数, getline函数读入字符的时候会将一行内的回车符读入,
这样for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
这里能读入lime-1个字符,然后加上一个回车符,最后还要加一个字符串结束符。
字符总数为lime+1.
造成主函数里德line数组越界写.

/* getline函数: 将一行读入大到s中并返回其长度 */
int getline(char s[], int lim)
{
int c, i;

for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n'){ //这里会把回车符写入
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}


修改方法:
把上面函数里的
if (c == '\n'){ //这里会把回车符写入
s[i] = c;
++i;
}
去掉,即字符串不读取换行符.
或者,
修改for循环:
for (i=0; i<lim-2 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;

或者,
将主函数里的line数组和longest数组都加一个长度,如:
longest[MAXLINE + 1];
十八道胡同 2010-05-19
  • 打赏
  • 举报
回复
奇怪,你的line貌似没有赋值。。。
十八道胡同 2010-05-19
  • 打赏
  • 举报
回复
肯定越界了
dongnanfanlin 2010-05-19
  • 打赏
  • 举报
回复
这个数组总共是存放 lim 个值

程序之前只赋值了 lim-1 个值到 s 数组里,最后一个 s[i] 存放 '\0',保证字符串结束

如果按你那么写 i<=lim-1 ,则这个数组里的值都填满了,不一定会有结束符

输出时会把这个字符串首地址的内存开始输出,直到结束为止,可能会输出一些乱码

所以实际中数组定义一般会多定义一个字符,最后赋 '\0' 。
pengzhixi 2010-05-19
  • 打赏
  • 举报
回复
有这种反映说明你越界了。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧