K& R练习1.17

时间:2015-12-26 04:48:16

标签: c arrays multidimensional-array

#include <stdio.h>

#define maxWordLength 100
#define working puts("working");

int getline1(char _line[], int _maxWordLength);
void copy(char to[][maxWordLength], char from[], int _rowCounter);


int main (int argc, char *argv[])
{
    char line[maxWordLength];
    char moreThanEightySet[maxWordLength][maxWordLength];                                       //2D array to store lines with characters more than eighty   

    int r_length;  
    int rowCounter = 0;
    int i, j = 0;

    while((r_length = getline1( line, maxWordLength)) > 0)
    {   
        if(r_length > 5)    //5 for testing the condition
        {
            copy( moreThanEightySet, line, rowCounter); 
            rowCounter++;
        }   
    }

    for(i = 0; i < rowCounter; i++)
    {
        printf("\n %s", moreThanEightySet[rowCounter]);
    }


    return 0;
}
int getline1(char _line[], int _maxWordLength)                                                  //reads line inputs and returns the number of characters
{
    int i, c;


    for(i = 0 ; i < _maxWordLength - 1 && (c = getchar()) != EOF && c != '\n' ; i++)
    {
        _line[i] = c;
    }

    if(c == '\n')
    {
        _line[i + 1] = '\n' ;
    }

    _line[i + 1] = '\0' ;

    return i;
}
void copy(char to[][maxWordLength], char from[], int _rowCounter)   
{

    int i = 0;

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

我正在关注K&amp; R此时尚未引入多维数组,但我想试验并使用2d数组来存储大于80个字符的行这是使用2d数组的正确方法吗?我得到一个分段错误,任何人都可以指出错误发生在哪里 谢谢

P.S我根据评论编辑了程序,并且出于某种原因,2d阵列接缝无法打印

3 个答案:

答案 0 :(得分:1)

我发现以下行有问题可能会导致您出现分段错误

copy( moreThanEightySet[maxWordLength][maxWordLength], line, rowCounter); 

这条线有两个问题。 1)moreThanEightySet [100] [100] // maxWordLength = 100,因为你定义它。 请理解当您定义这样的数组时,它将从索引0开始到99 不是100 .index 100 无效。因此,您可以访问此数组直到moreThanEightySet [ 99] [99](这将是最后一个元素)。 在上面的行中,您尝试访问moreThanEightySet [100] [100] //这是无效的,可能会导致您出现分段错误。

2)复制功能的签名如下:

void copy(char to[maxWordLength][maxWordLength], char from[], int _rowCounter)

这意味着它将接受一个二维数组和一个一维数组以及一个整数但是当你调用这个函数时,看看你作为第一个参数传递了什么。

 copy( moreThanEightySet[maxWordLength][maxWordLength], line, rowCounter); 

第一个agrument在更多的地方,而是在第十八个[100] [100]。它不是二维数组。内部复制功能你正在写这个值。

<强>解决方案: copy(moreThanEightySet,line,rowCounter); //传递数组而不是特定元素

我在复制功能中发现的问题很少。

void copy(char to[maxWordLength][maxWordLength], char from[], int _rowCounter)  
{

    int i; //undefined value of i .I think it should be 0 .

    while((to[_rowCounter][i] = from[i]) != '\0')
        i++;
    _rowCounter++;  //you should not increment rowcounter here as it is not doing anything .Ideally you should increment _rowCounter from the position you are calling this function "copy" 
}

见上述功能中的评论。

 while((r_length = getline1( line, maxWordLength)) > 0)
    {   
        if(r_length > 80)
            copy( moreThanEightySet[maxWordLength][maxWordLength], line, rowCounter);
rowCounter++;//you should increment counter here .       
    }

我希望这会有所帮助。

答案 1 :(得分:1)

由于这是第1章的练习,我试图找到一个解决方案,只有那时学到的工具。这是我的代码:

#include <stdio.h>
#define MAXLINE 1000 /* maximum input of chars in the line */
#define MAXTEXT 50000 /* input maximun of chars in the text */
#define MINLINE 80 /* minimun input to print */

int getline(char line[], int maxline);
int concat(char line[], char base[], int position, int len);

main(){
    int len;
    int maxLine;    

    char line[MAXLINE];
    char base[MAXLINE];
    int pos;
    pos = 0;
    while ( (len = getline(line, MAXLINE)) > 0)
        if (len > MINLINE) //Testing if the line has more than 80 chars
            pos = concat(line, base, pos, len);
    printf("Text:\n%s", base);
    return 0;
}

/* Concat the lines */
/* Keeps track of the postion */
int concat(char line[], char base[], int position, int len){
    int i ;
    for (i = 0; i< len && position < MAXTEXT ; i++){
        base[position] = line[i];
        position++;
    }
    return position;
}

/*getline: read a line, return length*/
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;
}

我只是将文本存储在char数组中(代码中的“base”)。为了实现这一点,有必要连接线(使用函数“concat”)并跟踪位置以继续添加线。通过这种方式,代码可以控制要添加的行,而不是。

PS:我建议将MINLINE定义中的80改为较低的数字以便轻松测试。

答案 2 :(得分:0)

参考我的评论编号#1:

我已经编辑了我的代码(正如我在之前的评论中所建议的那样)。这是完整的工作代码。 我个人觉得这段代码可以进一步改进。

#include <stdio.h>

#define maxWordLength 100

int getline1(char _line[], int _maxWordLength);
void copy(char to[maxWordLength][maxWordLength], char from[], int _rowCounter);

int main (int argc, char *argv[])
{

    char line[maxWordLength]={0};
    char moreThanEightySet[maxWordLength][maxWordLength]={0};                                       //2D array to store lines with characters more than eighty   

    int r_length;  
    int rowCounter = 0;
    int i;

    while((r_length = getline1( line, maxWordLength)) > 0)
    {   
        if(r_length > 80)
            copy( moreThanEightySet, line, rowCounter);

            rowCounter++; //right place to increment it
    }

    for(i = 0; i < rowCounter; i++)
    {
        printf("\n %s", moreThanEightySet[i]);
    }


    return 0;
}
int getline1(char _line[], int _maxWordLength)                                                  //reads line inputs and returns the number of characters
{
    int  i;
    char c;

    for(i = 0 ; i < _maxWordLength - 1 && (c = getchar()) != EOF && c != '\n' ; i++)
    {

        _line[i] = c;
    }

    if(c == '\n')
    {
        _line[i + 1] = '\n' ;
    }
    if(c == '\0')
    {
       _line[i + 1] = 0; ; //I personally feel this condition is not required 
    }

    return i;
}
void copy(char to[maxWordLength][maxWordLength], char from[], int _rowCounter)  
{

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

请注意,由于某些原因,您的代码中包含以下条件。

if(r_length > 80)
                copy( moreThanEightySet, line, rowCounter);

表示从&#34; line&#34;复制to&#34; moreThanEightySet&#34;直到,除非输入超过80个单词。请在给出输入的同时考虑它并且#34;复制&#34;将不会被调用,因此你最终将不打印内容&#34; moreThanEightySet&#34; 。 如果您遇到任何其他问题,请告诉我。