我正在尝试增加C字符数组中的值,并且它会一直失败 - 帮助?

时间:2010-08-17 18:06:19

标签: c

这是我的函数代码:

char * increment_b_string(char * b_string)
{
    char * ret_string = (char *) malloc(7);

    ret_string = "001aaa";

    if (*(b_string + 2) == '9')
    {
        *(ret_string +2) == '0';

        if (*(b_string + 1) == '9')
        {
            *(ret_string +1) = '0';
            *(ret_string) = *(b_string) + 1;
        } else {
            *(ret_string + 1) = *(b_string + 1) + 1;
        }
    } else {
        *(ret_string + 2) = *(b_string + 2) + 1;
    }

    return ret_string;
}

有关为什么会失败的任何想法?

一般的想法是b_string将包含类似“123aaa”的值。 “aaa”部分并不重要,永远不会改变。只有前3个数字会。它们需要增加,就好像它们是整数一样。需要在开始时保留前导零。因此,如果输入为“004aaa”,则输出应为“005aaa”。这只需要达到“300aaa”,因此我不会考虑更多的东西。这是一个学校的编程任务,因此问题非常人为。

感谢。

编辑:我改变了我的功能。这就是现在的情况。

void increment_b_string(char * b_string)
{   
    if (b_string[2] == '9')
    {
        b_string[2] == '0';

        if (b_string[1] == '9')
        {
            b_string[1] = '0';
            b_string[0] += 1;
        } else {
            b_string[1] += 1;
        }
    } else {
        b_string[2] += 1;
    }
}

假设b_string最初填充了...

strcpy(b_string,“001aaa”);

......这是对的吗?我的程序仍然表现出相同的行为,但这可能是代码中其他地方的错误。

6 个答案:

答案 0 :(得分:14)

您不能增加或更改字符串文字 - 它们只能在C中读取,这就是您正在做的事情。

char * ret_string = (char *) malloc(7);
ret_string = "001aaa";

不执行您认为的操作,它不会将字符串复制到malloced空间ret_string指向,它将ret_string设置为指向字符串文字“001aaa”。请改用:

 char * ret_string = (char *) malloc(7);
 strcpy(ret_string,"001aaa");

答案 1 :(得分:2)

首先,我会通过以下方式初始化ret_string

char * ret_string = strdup("001aaa");

您目前将ret_string分配给字符串文字,当您要修改字符串时,您不想这样做。

请注意,完成后请致电free(ret_string)strdup的实施包含malloc

其次,如果使用语法b_string[i]而不是*(b_string + i),则可以更轻松地浏览函数的逻辑。它们是等价的。

修改

由于strdup不是ANSI C,因此您始终可以使用相同的功能定义自己的函数,例如:

char *strdup (const char *s) {
    char *d = (char *)(malloc (strlen (s) + 1));
    if (d == NULL) return NULL;
    strcpy (d,s);
    return d;
}

参考:

strdup() - what does it do in C?

答案 2 :(得分:1)

这些都没有经过测试,但以下情况应该会有效。

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

/* Many libc implementations have strdup, but some don't */
char * strdup(const char * str) {
     char * copy = malloc(strlen(str)+1);
     if (copy) {
         strcpy(copy, str);
     }
     return copy;
}


/* This increments the first ASCII integer it finds within the string by one.
 * The integer is treated as though it is base 10 for the purposes of incrementing
 * and in the event that the upper digit is '9' before the increment it is '0' after
 * the increment and the carry digit is lost.
 */ 
char * increment_b_string_inplace(char * str) {
     char * s = str;
     while (*s) {  /* Look for where the number starts. */
        char c = *s;
        if (isdigit(c)) { 
            /* This is the start of a number! */
            char * e = s+1;
            unsigned carry;
            while (isdigit(*++e) ) {;} /* find where the number ends */ 
            e--;  /* we went 1 too far, so back up */
            do {   /* Do the actual increment. ][
                unsigned i = *e - '0';
                i++;
                carry = i % 10; /* this should always be 0 or 1 */
                *e = (char)('0' + (i / 10) );
                e--;
            } while (e<=s && carry);
        }
    }
    return str;
}


/* This is the function you originally wanted. */
char * increment_b_string(const char * b_string)
{
    char * str = strdup(b_string);

    if (!str) {
        return str;
    }
    return increment_b_string_inplace(str);
}

您也可以将整个整数读入一个int变量,然后将其递增,然后将其转换回字符串。

答案 3 :(得分:1)

下面是实现我认为你想要的代码。包括重写您的increment_b_string。它使用strtol(string to long)和sprintf分别从string转换为int和back。假设increment_b_string将在其上运行的字符串始终为dddccc格式(d = digit,c = character)。

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

char * increment_b_string(char * b_string)
{
    char * ret_string;
    int   int2inc;

    ret_string = malloc(sizeof(b_string));
    int2inc = (int) strtol(b_string, ret_string, 10);
    int2inc ++;
    sprintf(ret_string, "%03d%s", int2inc, &b_string[3]);
    return ret_string;
}

int main(void) {
    char the_string[7] = "000aaa";
    printf("before, the_string = \"%s\"\n", the_string);
    strcpy(the_string, increment_b_string(the_string));
    printf("after, the_string = \"%s\"\n", the_string);
}

输出结果为:

  

之前,the_string =“000aaa”
  之后,the_string =“001aaa”

答案 4 :(得分:0)

另外,如果执行了else子句,你的ret_string将在前面有一个或两个零,这应该是别的东西。要解决此问题,您需要从b_string初始化ret_string,而不是从常量:

char * ret_string = strdup(b_string);

答案 5 :(得分:0)

严格使用C89的解决方案,没有malloc / strdup,对于可变输入字符串更灵活:

char *inc_bstr(char *str)
{
  char *e,f[] = "%03ld%s";
  long i = strtol(str,&e,10)+1;
  f[2] = '0'+(e-str);
  sprintf(str,f,i>300?300:i,e);
  return str;
}

...
char x1[]="0aaa";
puts(inc_bstr(x1));
...
char x2[]="00aaa";
puts(inc_bstr(x2));
...
char x3[]="000aaa";
puts(inc_bstr(x3));
...
char x4[]="0000aaa";
puts(inc_bstr(x4));
...
char x5[]="00000aaa";
puts(inc_bstr(x5));
...
char x6[]="0000bb";
puts(inc_bstr(x6));
...
char x7[]="000";
puts(inc_bstr(x7));
...
char x8[]="000xxx",z=99;
while( z-- )
  puts(ins_bstr(x8));