【问题标题】:K&R 1-19 // About adjusting the value of numerical countersK&R 1-19 //关于调整数值计数器的值
【发布时间】:2015-02-03 13:46:13
【问题描述】:

这是对K&R教科书的一个练习的一个非常奇怪的疑问,我不知道“标准”答案是什么,所以程序本身可能有点陌生。

我试图在代码中描述将这个程序组合在一起的增量步骤,我的问题是关于按逻辑不应该产生任何影响但带走流浪--i的调整。

相反,如果我尝试它,就会出现各种奇怪的行为(我尝试了一些组合,所以我不会在这里描述它们。)

#include <stdio.h>
#define MAXCHAR 15
int storeline(char line[], int lim);
void reverse(char in[], char out[], int len);
main() {
    int l;
    char line[MAXCHAR+2]; /*I add two position to accomodate a newline and a '\0' character */
    char enil[MAXCHAR+2];
    while ((l=storeline(line, MAXCHAR+2))>=0) {
        if (l<MAXCHAR)
            reverse(line, enil, l); /*reverse is called with the array (in this case a 17 characters array) and the count computed in storeline (up to )*/
        else
            reverse(line, enil, MAXCHAR);
        printf("%s", enil); 
    }
    return 0;
}

int storeline(char s[], int lim) {
    int i;
    int c;
    for(i=0;i<lim-2&&(c=getchar())!='\n'&&c!=EOF;++i){ /* this loop breaks at i==15 */
        if (c==' '||c=='\t') {
            while((c=getchar())==' '||c=='\t');
            s[i]=' ';
            ++i;
            if(c==EOF)
                break;
        }
        s[i]=c;
    }
    if (c!=EOF) {
        s[i]='\n'; /* a newline is added in s[15] */
        ++i;
    }
    s[i]='\0'; /* a '\0' character is added at s[16] */
    --i; /*no more characters have to be added so I bring the count of the characters down by 1 (a further unit is deducted by the fact that one character is stored in s[0] */
    while (c!='\n' && c!= EOF) {
        c=getchar();
        i++;
    }
    return i; /* the count goes on and is subsequently returned by the function, newline is assumed to be a file break by design, but this is easily adjusted */
}

/* let's pretend the string was '123451234512345' and MAXCHAR is 15. */
void reverse (char in[], char out[], int len) {
    int i, lim;
    i=0;
    lim=len-1; /*len was 15, now it is 14. note that the array goes up to in[16] */
    while(lim>=0) {
        out[i]=in[lim];
        ++i;
        --lim;
    }
    out[i]='\n';
    ++i;
    out[i]='\0';
}

我的疑问是,如果我删除 storeline 中的 --i 元素并将 lim 减少到 len-2 一切都应该像以前一样工作,但它没有/为什么?这些数字实际上是相同的..

【问题讨论】:

  • 注:c 可能在if (c!=EOF) 中未定义lim &lt;= 2
  • Gaah,一个包含getchar() 的循环,其中包含对getchar() 的条件调用......这不是最好的方法。每次迭代读取一个字符。
  • 您是否尝试过使用调试器单步执行? (或者只是添加一些打印语句来跟踪执行。)
  • @chux 如果我明白你的意思,我会假设 lim 永远不会设置为小于 2(因为整个事情是如何工作的)
  • @unwind 是的,它看起来不太好,但这是有效的,因为它意味着丢弃字符(这样输出在单词之间不会有超过一个空格,并且制表符减少到一个空格)

标签: c kernighan-and-ritchie


【解决方案1】:

我不确定我是否得到它,但你试图混淆 1.18 和 1.19。一方面,您想清理输入,另一方面,您试图反转线路。我建议你把你想做的事情分成不同的功能。它不仅使编程更容易,而且更容易检测错误。这样,我将创建一个函数来获取该行并将其存储到一个数组中,与书中给出的示例完全相同。然后,我会做第二个功能来清理线条和第三个功能来反转线条。但是,如果你只想解决练习 1.19,你只需要使用 getline 和 reverse 函数。我把编写 main() 函数的部分留给你。

这样,getline函数:

int getline(char line[], int maxsize)
{
    int position, input_character;
    input_character = 0;
    for (position = 0; position < maxsize - 2 && (input_character = getchar()) != EOF && input_character != '\n'; ++position) {
        line[position] = input_character;
    }
    if (input_character == '\n') {
        line[position] = input_character;
        ++position;
    }
    line[position] = '\0';
    return position;
}

清洁功能:

void clean(char output[], char input[]) 
{
    char storage[MAXLINE];
    int output_character, storage_character, input_character;
    output_character = 0;
    storage_character = 0;

    while (output[output_character] != '\0') {                                                  //This goes through output[] until it gets to the last written character
        ++output_character;
    }

    for (input_character = 0; input[input_character] != '\0' && output_character < (MAXCHAR * MAXLINE - 1); ++input_character) {
        if (input[input_character] == ' ' || input[input_character] == '\t') {
            storage[storage_character] = input[input_character];                                //The array storage[] will store me the trailing blanks and tabs
            ++storage_character;
        }
        else if (input[input_character] == '\n') {          //If there is a newline character and nothing has been copied into output, then it is a blank line and is not copied into output
            if (output[output_character] == '\0') {
                ;
            }
            else {
                output[output_character] = input[input_character];                                  //Copy the newline character
                ++output_character;
            }
        }
        else {
            storage[storage_character] = '\0';
            for (storage_character = 0; storage[storage_character] != '\0'; ++storage_character) {
                output[output_character] = storage[storage_character];                              //If there is a character after blanks/tabs, copy storage into output
                ++output_character;
            }
            output[output_character] = input[input_character];                                  //Copy the character
            ++output_character;
            storage_character = 0;
        }
    }
    output[output_character] = '\0';
}

还有反向功能:

void reverse(char reversed[], char original[])
{
    int size_original, output_char;
    for (size_original = 0; original[size_original + 1] != '\n'; ++size_original) {
        ;
    }
    for (output_char = 0; size_original >= 0; ++output_char) {
        reversed[output_char] = original[size_original];
        --size_original;
    }
    reversed[output_char] = '\n';
    reversed[output_char + 1] = '\0';
}

我希望这很有用。如果没有帮助,请随时发表评论,我会尽力为您解答。

【讨论】:

    猜你喜欢
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多