C K&;R练习1-19

C K&;R练习1-19,c,arrays,function,C,Arrays,Function,上下文:我有JAVA编程的经验,所以这可能是阻止我理解这个问题的原因。练习1-19要求编写一个反转函数,反转串起的字符。使用它编写一个程序,每次将其输入反转一行 注意:我稍微修改了输入参数,使其也采用字符数组的长度 此解决方案有故障,如下所示 函数:(是和否分别是值1和0的常数) 输出: $./a.out < example > output; cat output olleh sihth sih h emh h

上下文:我有JAVA编程的经验,所以这可能是阻止我理解这个问题的原因。练习1-19要求编写一个反转函数,反转串起的字符。使用它编写一个程序,每次将其输入反转一行

注意:我稍微修改了输入参数,使其也采用字符数组的长度

此解决方案有故障,如下所示

函数:(是和否分别是值1和0的常数)

输出:

     $./a.out < example > output; cat output


    olleh
    sihth
    sih
    h
    emh
    h
    dna


    edoc

    edoc
$./a.out输出;cat输出
奥利
希思
sih
H
有效市场假说
H
脱氧核糖核酸
埃多克
埃多克
我有一种感觉,它与在函数中创建字符数组有关,因为当我在没有创建新的字符数组的情况下反转它时(显然更好),它工作得很好。然而,我仍然不明白这个代码的问题是什么

编辑:下面是一个不使用数组创建的工作函数,这意味着“/n”、“0”不是错误

    /* Similar to @DNT suggestion, I believe.. this function works.*/
    void reverse(char input[] , int lim)
{
    int j , nl_check;
    nl_check = NO;
    for(j=0; j<lim-1 && input[j]!='\0'; ++j)
    {
    if(input[j] == '\n')
    {
        nl_check = YES ;
        break;
    }
    }

    int i,z;
    char tmp='\0';
    --j;
    for(i=0,z=j; i!=((j+1)/2) ; ++i,--z)
    {
    tmp = input[i];
        input[i] = input[z];
        input[z] = tmp;
    }
    if(nl_check==YES)
    {
    input[++j]='\n';
    }
    input[++j] = '\0';
}
/*类似于@DNT建议,我相信。。这个功能有效*/
无效反转(字符输入[],int lim)
{
int j,nl_检查;
nl_检查=否;
对于(j=0;j,这里有一个例子:

#include <stdio.h>
#include <string.h>

void reverse(char a[], int sz)
{
    int k, i,j;
    for (i = 0, j = sz-1; i< sz/2; ++i, --j)
    {
        k = a[j];
        a[j] = a[i];
        a[i] = k;
    }
};

int main() {
  char x[] = "abcdefg\nsecond line\nthird line";
  char *p = strtok(x, "\n");
  while(p)
  {
    reverse(p, strlen(p));
    printf("%s\n", p);
    p = strtok(NULL, "\n");
  }
}

在将任何内容写入
tmp
数组之前,您正在调用
printf(“%s”,tmp);
。我也不知道这在Java中是如何工作的。
printf(“%s”,tmp)
在函数为其元素分配任何值之前打印
tmp
。为什么有这一行?充其量,它打印以前调用函数时留在堆栈上的数据。
tmp[++i]='\n';
和第一个
tmp[++i]='\0'
可以溢出
tmp
的末尾。第二个
tmp[++i]='\0';
是不需要的,并且可能会超出
tmp
的末尾。可能是为了在
输入中输入一个空值,而不是
tmp
@MikeJalfrezi:现在你根本没有
printf
。请发布一个。谢谢你,我相信这是一个类似的逻辑,如果不是我的备用反向函数的话。它只是t我不知道为什么我的第一个函数是错误的。没有解释的代码不是一个好答案,也不能解释原始代码的错误。@MikeJalfrezi它有逻辑错误。它不会继续超过以\n结尾的第一行。您只在开始时检查一次换行,但在处理第一行代码之后ne,不循环检查字符串以获取更多信息。
    /* Similar to @DNT suggestion, I believe.. this function works.*/
    void reverse(char input[] , int lim)
{
    int j , nl_check;
    nl_check = NO;
    for(j=0; j<lim-1 && input[j]!='\0'; ++j)
    {
    if(input[j] == '\n')
    {
        nl_check = YES ;
        break;
    }
    }

    int i,z;
    char tmp='\0';
    --j;
    for(i=0,z=j; i!=((j+1)/2) ; ++i,--z)
    {
    tmp = input[i];
        input[i] = input[z];
        input[z] = tmp;
    }
    if(nl_check==YES)
    {
    input[++j]='\n';
    }
    input[++j] = '\0';
}
#include <stdio.h>
#include <string.h>

void reverse(char a[], int sz)
{
    int k, i,j;
    for (i = 0, j = sz-1; i< sz/2; ++i, --j)
    {
        k = a[j];
        a[j] = a[i];
        a[i] = k;
    }
};

int main() {
  char x[] = "abcdefg\nsecond line\nthird line";
  char *p = strtok(x, "\n");
  while(p)
  {
    reverse(p, strlen(p));
    printf("%s\n", p);
    p = strtok(NULL, "\n");
  }
}
void reverse(char input[] , int lim)
{
    int i, j, z, start=0;

    for(i=0; start< lim ; i++)
    {
        if (input[i] == '\n' || input[i] == '\0')
        {
            for (j=start, z = i-1; j< start+(i-start+1)/2; j++, z--)
            {
                char tmp = input[j];
                input[j] = input[z];
                input[z] = tmp;
            }
            start = i+1;
        }
    }
}