K& R C编程练习1-19

时间:2016-02-15 11:23:40

标签: c string char reverse kernighan-and-ritchie

作业:  写一个反映字符串s的函数reverse。使用它来编写一个程序,一次一行地显示它的输入

以下是我尝试解决问题的方法:

#include <stdio.h>
#define MAXLINE 1000

int  getlinex(char line[], int maxline);

int main(){
    int len, j;
    char line[MAXLINE];
    char *temp;
    while ((len = getlinex(line, MAXLINE)) > 0) {
        for(j=0; j<=len; j++){
            temp = &line[len-j];
            line[j] = *temp ;
        }
        printf("%s", line);
    }
}

int getlinex(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;
}

第二版

int getlinex(char line[], int maxline);

int main(){
    int len,j;
    char line[MAXLINE];
    while ((len = getlinex(line, MAXLINE)) > 0) {
        for(j=0;j<=len;j++){
            reverse(&line,j,len);
        }
        printf("%s",line);
    }
}

void reverse( char *s[], int i, int len){
    s[i] = s[len-i];
}

int getlinex(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 []数组,但它不仅仅在main中工作我会对字符串进行处理。

问题出在哪里?

4 个答案:

答案 0 :(得分:0)

正如在作业中写的那样,你必须写一个相应的函数。它可以按照以下方式进行,如演示程序中所示。

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

char * reverse( char *s )
{
    size_t n = strlen( s );

    for ( size_t i = 0; i < n / 2; i++ )
    {
        char c = s[n-i-1];
        s[n-i-1] = s[i];
        s[i] = c;
    }

    return s;
}

int main( void )
{
    char s[] = "Hello, World!";

    puts( s );
    puts( reverse( s ) );
}    

它的输出是

Hello, World!
!dlroW ,olleH

关于程序中的循环

         for(j=0;j<=len;j++){
            temp = &line[len-j];
            line[j] = *temp ;
            }

然后它没有意义。例如,当j等于0时,循环体刚刚用line[0]处存储的字符覆盖&line[len],该字符等于字符串的终止零。您需要将头部中的字符与字符串尾部的字符交换。

考虑到函数getlinex在字符串中包含新行字符。

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

也许你应该在反转它之前将它从字符串中删除。

例如

if ( line[len-1] == '\n' ) line[len-1] = '\0';

或者只是从函数if中删除上面显示的getlinex语句。

答案 1 :(得分:0)

考虑这个循环:

for(j=0;j<=len;j++){
    temp = &line[len-j];
    line[j] = *temp;
}

第一次,j0,因此temp设置为&line[len]。由于此指向\0的终止line字节,*temp\0。然后将其分配到line[j],即line[0]。之后发生了什么并不重要,因为line的第一个字节终止了字符串。

这解释了为什么你会看到一个空字符串作为结果。但即使修复了这个特殊问题,字符串也会就地反转,所以一旦它到达字符串的中间,剩下的字符就会被覆盖并且不再可用。解决方法是交换字符对,而不是仅仅复制一个字符。

答案 2 :(得分:0)

以下是我在进行KnR练习时编写的代码。

#include <stdio.h>

/* exercise 1.19 */

#define MAXLEN 1000

int getline(char s[], int len);
void reverse(char s[]);

int
main(){
    int len;
    char line[MAXLEN];

    while ((len=getline(line,MAXLEN))){
        reverse(line);
        printf("%d - %s",len, line);
    }

    return 0;
}

/*
 * Reads a line from stdin
 */
int getline(char s[], int len){
    int c, i;

    for (i = 0; i < len -1 && (c=getchar()) != EOF && c != '\n'; ++i)
    s[i] = c;

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

    s[i]='\0';
    return i;
} 


/*
 *  Reverses the order of chracters in string s
 */
void reverse(char s[]){
    int i, k;
    char tmp[MAXLEN];

    i = 0;
    /* copy the character string */
    while ((tmp[i] = s[i]) != '\0')
        ++i;

    --i; /* last character is nil */

    for (k = 0; k <= i ; ++k)
        s[k] = tmp[i-k];

    s[k] = '\0';
}

答案 3 :(得分:0)

以下是我的实现。它遵循功能样式。

#include <stdio.h>
#define MAXLINE 1000

int getline(char org[], int maxline);
void reverse(char rev[], char org[], int len);

int main(void) {
    char org[MAXLINE];
    char rev[MAXLINE];
    int len;
    while ((len = getline(org, MAXLINE)) > 0) {
        if (len > 0) {
            reverse(rev, org, len);
            printf("%s", rev);
        }
    }
    return 0;
}

int getline(char org[], int maxline) {
    int i = 0, c;
    for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; i++) {
        org[i] = c;
    }
    if (c == '\n') {
        org[i] = '\n';
        i++;
    }
    org[i] = '\0';
    return i;
}

void reverse(char rev[], char org[], int len) {
    int i;
    for (i = 0; i < len; i++) {
        rev[len - i] = org[i];
    }
    rev[0] = '\b';
    rev[1] = '\b';
    rev[len + 1] = '\n';
    rev[len + 2] = '\0';
}