在C函数中返回字符串

时间:2016-08-25 18:05:27

标签: c string char

我试图在其中一个在线编码网站上解决 CountAndSay 问题,但我无法理解为什么我的程序正在打印NULL。我确信我在做一些概念上的错误,但没有得到它。

这是我的代码:

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

char* countAndSay(int A) {
    int i,j,k,f,count;
    char a;

    char *c = (char*)malloc(sizeof(char)*100);
    char *temp = (char*)malloc(sizeof(char)*100);
    c[0] = 1;c[1] = '\0';
    for(k=2; k<=A; k++)
    {
        for(i=0, j=0; i<strlen(c); i++)
        {    
            a = c[i];
            count = 1;
            i++;

            while(c[i] != '\0')
            {
                if(c[i]==a)
                {
                    count++;
                    i++;
                }
                else if(c[i] != a)
                {
                    i--;
                break;
                }
                else
                {
                break;
                }
            }
            temp[j] = count;
            temp[j+1] = a;
            j += 2;
        }
        *(temp+j) = '\0';
        if(k<A)
        {
        for(j=0; j<strlen(temp); j++)
        {
                c[j] = temp[j];
        }
        c[j] = '\0';
        }    
    }
    return temp;
}

int main(void) {
    // your code goes here
    char *c = countAndSay(8);
    printf("%s\n",c);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

这个想法并没有那么糟糕,主要的错误是数字和字符的混淆,如评论中所示。

另外:如果使用动态内存,则使用动态内存。如果您只想使用固定的金额,则应使用堆栈,例如:c[100],但评论中也会出现这种情况。您还只需要一块内存。以下是基于您的代码的工作示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ALL CHECKS OMMITTED!
char *countAndSay(int A)
{
  int k, count, j;
  // "i" gets compared against the output of
  // strlen() which is of type size_t
  size_t i;
  char a;

  // Seed needs two bytes of memory 
  char *c = malloc(2);
  // Another pointer, pointing to the same memory later.
  // Set to NULL to avoid an extra malloc()
  char *temp = NULL;
  // a temporary pointer needed for realloc()-ing
  char *cp;
  // fill c with seed
  c[0] = '1';
  c[1] = '\0';
  if (A == 1) {
    return c;
  }
  // assuming 1-based input, that is: the first 
  // entry of the sequence is numbered 1 (one)
  for (k = 2; k <= A; k++) {
    // Memory needed is twice the size of
    // the former entry at most.
    // (Averages to Conway's constant but that
    // number is not usable here, it is only a limit)
    cp = realloc(temp, strlen(c) * 2 + 1);
    temp = cp;
    for (i = 0, j = 0; i < strlen(c); i++) {
      //printf("A i = %zu, j = %zu\n",i,j);
      a = c[i];
      count = 1;
      i++;
      while (c[i] != '\0') {
        if (c[i] == a) {
          count++;
          i++;
        } else {
          i--;
          break;
        }
      }
      temp[j++] = count + '0';
      temp[j++] = a;
      //printf("B i = %zu, j = %zu\n",i,j-1)
      //printf("B i = %zu, j = %zu\n",i,j);
    }
    temp[j] = '\0';
    if (k < A) {
      // Just point "c" to the new sequence in "temp".
      // Why does this work and temp doesn't overwrite c later?
      // Or does it *not* always work and fails at one point?
      // A mystery! Try to find it out! Some hints in the code.
      c = temp;
      temp = NULL;
    }
    // intermediate results:
    //printf("%s\n\n",c);
  }
  return temp;
}

int main(int argc, char **argv)
{
  // your code goes here
  char *c = countAndSay(atoi(argv[1]));
  printf("%s\n", c);
  free(c);
  return 0;
}

为了找到一种方法来检查不在OEIS列表中的序列,我在我的阁楼里翻找了一下这个小小的&#34;宝石&#34;:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>

char *conway(char *s)
{
  char *seq;
  char c;
  size_t len, count, i = 0;

  len = strlen(s);
  /*
   * Worst case is twice as large as the input, e.g.:
   * 1 -> 11
   * 21 -> 1211
   */
  seq = malloc(len * 2 + 1);
  if (seq == NULL) {
    return NULL;
  }
  while (len) {
    // counter for occurrences of ...
    count = 0;
    // ... this character
    c = s[0];
    // as long as the string "s" 
    while (*s != '\0' && *s == c) {
      // move pointer to next character
      s++;
      // increment counter
      count++;
      // decrement the length of the string
      len--;
    }
    // to keep it simple, fail if c > 9
    // but that cannot happen with a seed of 1
    // which is used here.
    // For other seeds it might be necessary to
    // use a map with the higher digits as characters.
    // If it is not possible to fit it into a
    // character, the approach with a C-string is
    // obviously not reasonable anymore.
    if (count > 9) {
      free(seq);
      return NULL;
    }
    // append counter as a character
    seq[i++] = (char) (count + '0');
    // append character "c" from above
    seq[i++] = c;
  }
  // return a proper C-string
  seq[i] = '\0';
  return seq;
}


int main(int argc, char **argv)
{
  long i, n;
  char *seq0, *seq1;

  if (argc != 2) {
    fprintf(stderr, "Usage: %s n>0\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  // reset errno, just in case
  errno = 0;
  // get amount from commandline
  n = strtol(argv[1], NULL, 0);
  if ((errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))
      || (errno != 0 && n == 0)) {
    fprintf(stderr, "strtol failed: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }

  if (n <= 0) {
    fprintf(stderr, "Usage: %s n>0\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  // allocate space for seed value "1" plus '\0'
  // If the seed is changed the limit in the conway() function
  // above might need a change.
  seq0 = malloc(2);
  if (seq0 == NULL) {
    fprintf(stderr, "malloc() failed to allocate a measly 2 bytes!?\n");
    exit(EXIT_FAILURE);
  }
  // put the initial value into the freshly allocated memory 
  strcpy(seq0, "1");
  // print it, nicely formatted
  /*
   * putc('1', stdout);
   * if (n == 1) {
   * putc('\n', stdout);
   * free(seq0);
   * exit(EXIT_SUCCESS);
   * } else {
   * printf(", ");
   * }
   */
  if (n == 1) {
    puts("1");
    free(seq0);
    exit(EXIT_SUCCESS);
  }
  // adjust count
  n--;
  for (i = 0; i < n; i++) {
    // compute conway sequence as a recursion
    seq1 = conway(seq0);
    if (seq1 == NULL) {
      fprintf(stderr, "conway() failed, probably because malloc() failed\n");
      exit(EXIT_FAILURE);
    }
    // make room
    free(seq0);
    seq0 = NULL;
    // print sequence, comma separated
    // printf("%s%s", seq1, (i < n - 1) ? "," : "\n");
    // or print sequence and length of sequence, line separated
    // printf("%zu: %s%s", strlen(seq1), seq1, (i < n-1) ? "\n\n" : "\n");
    // print the endresult only
    if (i == n - 1) {
      printf("%s\n", seq1);
    }
    // reuse seq0
    seq0 = seq1;
    // not necessary but deemed good style by some
    // although frowned upon by others
    seq1 = NULL;
  }
  // free the last memory
  free(seq0);
  exit(EXIT_SUCCESS);
}