#include<stdio.h>
#define MAXLINE 1000 /*max input line length*/
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*here is just to print the longest line user type into*/
int main()
{
int len; //current line length
int max; //maximum length to keep
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("line content=====: %s", longest);
}
return 0;
}
int getline(char line[], int maxline)
{
//here we use to get the input sentence.
int ch = getchar();
int i = 0;
while(ch != '\n'&&ch != EOF)
{
line[i++] = ch;
ch = getchar();
}
line[i] = '\0';
printf("len>>>>: %d\n",i);
return i;
}
void copy(char to[], char from[])
{
printf("come to copy method....\n");
int i = 0;
while(from[i] != '\0')
{
to[i] = from[i];
i ++;
}
//add the '\0' at the end of string, I think this is nessary!
to[i] = '\0';
}
这是在C语言程序设计(第二版)(丹利斯里奇经典)中的关于 《参数-传值调用》的一段代码。
运行结果:
这边能明白的事情是这样子的,我们总是在限定字符数组的长度,这边规定了一个最大的长度MAXLINE,往往我们也会想着,如果长度超过了这个限定的时候,或者输入的句子长度足够长的时候,我们又会应该是怎么去处理的呢?
若是这样子,能否可以在读取字符的时候,不断的重新分配新的空间,释放原来的空间,新的空间比原来的空间大,在释放原来的空间之前把里面的内容都复制到新的空间上面,这样子,就可以得到我们预想的处理方法,但可行性在意料之外!首先我们修改getline方法(注意引入stdlib.h和string.h),其中的思想如刚刚所描述的那样:
int getline(char *line)
{
//here we don't need any variables
//因为这边输入的是一个长度不限的,所以,这边需要动态的分配空间
int ch = getchar();
int i = 0;
//define a temp char pointer
char *temp;
int n= 0;
//at first time, we just malloc first
line = (char *)malloc(sizeof(char));
while(ch != '\n')
{
//malloc one space first
temp = line;
line = (char *)malloc((strlen(temp))*sizeof(char));
//put the new char into array
line[n] = ch;
//free space
free(temp);
ch = getchar();
}
line[n] = '\0';
printf("line = %s\n", line);
printf("length of new line: %d\n", n);
return n;
}
上面的getline方法只有一个char类型的指针,没有所谓的长度限制,测试:
int main()
{
int len; //current line length
int max = 0; //current max length line
char *line, *longest, *temp;
while( (len = getline(line))> 0)
{
if(len > max)
{
max = len;
temp = longest;
longest = (char *)malloc(sizeof(char)* (strlen(line)+1));
strcpy(longest, line);
free(temp);
}
}
if(max > 0)
{
printf("line content: %s",longest);
}
return 0;
}
然后测试的结果如下:
控制台也显示正常:
Compilation results...
--------
- Errors: 0
- Warnings: 0
- Output Filename: E:\ocode\get_longest_line.exe
- Output Size: 130.478515625 KiB
- Compilation Time: 0.51s
那现在的问题是什么?这明显是语法问题,这边修正getline方法和main测试方法:
char *getline()
{
//here we don't need any variables
//因为这边输入的是一个长度不限的,所以,这边需要动态的分配空间
int ch = getchar();
int i = 0;
//define a temp char pointer
char *temp, *line;
//temp length of line
int len = 0;
//real size of line
int n= 1;
//at first time, we just malloc first
line = (char *)malloc(sizeof(char));
printf("input new line: \n");
while(ch != '\n')
{
//malloc one space first
temp = line;
line = (char *)malloc((n+1)*sizeof(char));
strcpy(line, temp);
//put the new char into array
line[len++] = ch;
n++;
// printf("after input ch, n = %d length = %d\n",n, len);
//free space
free(temp);
ch = getchar();
}
line[len] = '\0';
return line;
}
测试:
int main()
{
int len; //current line length
int max = 0; //current max length line
char *line , *longest, *temp;
line = getline();
len = strlen(line);
longest = (char *)calloc(1,sizeof(char));
while( len > 0)
{
if(len > max)
{
max = len;
free(longest); //free longest space and create longer space
longest = (char *)malloc((max+1)*sizeof(char));
strcpy(longest, line);
}
free(line);
line = getline();
len = strlen(line);
}
if(max > 0)
{
printf("line content: %s",longest);
}
//at last, remember free space.
free(line);
free(longest);
return 0;
}
上面是可以暂时的输入任意长度的字符串,并记录下最长的字符串行,测试结果:
中间偶尔的会崩溃掉(在没有加入printf("input new line: \n");)不知道是不是真的有关系!!这个是为什么呢?崩溃出现了下面的提示:
这边,因为理解的不够深入,还有对于DEV-C的debug的不熟悉,有待学习,上面的问题待处理中......
想想看,这不是别人的问题,这是自己的问题,输入一个字符,把原来装满字符的数组控件进行扩大,这个扩大的过程是这样子的,重新的分配一个更大的控件,并且把原来的值重新的复制到新的字符控件,然后在把输入的字符也存储到最新分配的控件,然后把原来的控件给释放掉,这是正常的逻辑思维,如果真的想这样子动态的实现的话,有没有更好的想法,或者为什么这种方法是会出问题的呢,或者是看起来表面可行,可是内存中似乎出现了很多的躁动!!
想要彻底的明白为什么,所以,就是不断的补充新的C语言只是,另外,就是自己在重新的找个时间好好的debug下,试图看清内存中的行为和因为突然停止工作的原因。
试图跳过上面的问题,换成另外的一个问题,我们把原来的动态的更换字符串的存储空间现在转换成是固定的字符串控件,还是原来的实现方法,定义一个二位数组,保存我们在控制台上输入的值,然后写了下面的方法:
void read_line(char **lines)
{
int i,j;
char ch ;
i = 0;
j = 0;
for(; i< MAXLINE; i++)
{
printf("input new line: \n");
j = 0;
ch = getchar();
while(ch != '\n' && j < MAXLINE-1)
{
/**
因为不小心占用到了系统的内存吗?为什么这是常量区,也就是自己对变量的定义和生命其实
还是很模糊的阶段*/
lines[i][j] = ch;
j++;
ch = getchar();
}
if(j == 0)
{
break;
}
}
}
而测试类如下所示:
#include <stdio.h>
#include <stdlib.h>
#include "algorithm.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
//now this is a program and I can make some debug
char lines[MAXLINE/100][MAXLINE/10];
int i ;
read_line(lines);
i = 0;
for(; i<MAXLINE; i++)
{
if(strlen(lines[i]) < 80)
{
break;
}else{
printf("line-%d: %s",(i+1), lines[i]);
}
}
}
可是最后还是没有试验成功,这就是问题了还是上面弹出对话框的崩掉问题!!现在能想到的唯一的解决办法是进行debug!
这边调试到read_line的lines[i][j] = ch;的时候,出现了如下error:
很明显的说明这样的赋值行为是有背C语言的语法的,但是确实不明白这是为什么!因为我再main函数中已经是定义了lines的,也就是内存中应该是有这样的lines的二维字符存放空间的。
……网上无查询了相关的问题,出现这个问题是因为lines是常量,是不能对其进行修改里面的值的!很明显自己对C的字符串数组的定义或者声明还是很模糊的状态!
……
这边没有所谓的include和函数,直接集成到main方法中,然后可以很顺利的处理问题,因为限定死了字符串数组的大小,看起来显得有点牵强!
#include <stdio.h>
#define MAXLINE 1000
int main(int argc, char *argv[]) {
//now this is a program and I can make some debug
char lines[MAXLINE][MAXLINE];
int i, j;
char ch;
//read line
for(i= 0; i< MAXLINE; i++ )
{
j = 0;
printf("input new line: \n");
ch = getchar();
while( j < MAXLINE-1 && ch != EOF && ch != '\n' )
{
lines[i][j++] = ch;
ch = getchar();
}
if(j == 0)
{
//end of input
break;
}
}
i = 0;
for(; i<MAXLINE; i++)
{
if(strlen(lines[i]) < 10)
{
break;
}else{
printf("line-%d: %s\n",(i+1), lines[i]);
}
}
}