这是我的函数代码:
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”);
......这是对的吗?我的程序仍然表现出相同的行为,但这可能是代码中其他地方的错误。
答案 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;
}
参考:
答案 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));