C++ 用strcat将字符追加到C中的字符串
大家好,我仍然对指针感到困惑,我想知道是否有任何方法可以在不使用sprintf的情况下完成以下操作:C++ 用strcat将字符追加到C中的字符串,c++,c,C++,C,大家好,我仍然对指针感到困惑,我想知道是否有任何方法可以在不使用sprintf的情况下完成以下操作: char a[100], b[100], c[2]; //Some code that puts a string into a for(i = 0; i<strlen(a); i++) { if(a[i] == 'C') strcat(b, "b"); else if(a[i] == 'O') strcat(b, "a");
char a[100], b[100], c[2];
//Some code that puts a string into a
for(i = 0; i<strlen(a); i++)
{
if(a[i] == 'C')
strcat(b, "b");
else if(a[i] == 'O')
strcat(b, "a");
else if(a[i] == 'D')
strcat(b, "1");
else
{
sprintf(c, "%s", a[i]);
strcat(b, c);
}
}
b
。因此默认情况下charb[100]代码>具有垃圾值(在b
中可能不存在\0
)。但是字符串连接函数要求b
必须是字符串。所以
strcat(b, "b"); <--will Undefined Behavior
注意:半初始化数组的剩余元素将是0
(null),初始化
(3)是strcat(b,a[i])代码>错误:
要将单词上的a[i]
中的字符串连接到b
中,可以执行以下操作:
strcat(b, a + i);
是的,你是正确的strcat(b,a[i])代码>确实无效
注:a[i]
和(a+i)
不一样,a[i]
是字符类型,其中as(a+i)
是a
类型的字符串
假设您有以下字符串数组a
,且i
的值为2,则:
+----+----+----+---+---+----+----+----+---+
| 'u'| 's' |'e'|'r'|'5'| '6'| '7'|'8' | 0 |
+----+----+----+---+---+----+----+----+---+
201 202 203 204 205 206 207 208 209 210 211
^ ^
| |
a (a+i)
因此,在上图中,a
值为201
,类型为char[100]
(假设数组大小为100)(a+i)
还将'e'
中的字符串指向地址203
。其中asa[i]=“e”
所以你不能做strcat(b,a[i])代码>但strcat(b,a+i)
是有效的语法
此外,从@BenVoigt到concatn
chars Froma
Fromi
th位置,您可以执行以下操作:
strncat(b, a+i, n);
它将把n
字符从a+i
附加到b
将所有字符数组初始化为null,以便代码中不存在垃圾值
您正在附加到垃圾字符数组
char a[100]={0}, b[100]={0}, c[2]={0};
现在strcat()函数可以正常工作。有许多可能的方法可以按您的意愿执行。有一些方法可以避免同时使用strcat()
和sprintf()
——见下文;您可以在继续使用strcat()时避免使用sprintf()
我可能会这样做,即记录下一个字符将添加到目标字符串的位置,b
。这将更加有效,因为在每次构建一个字符的字符串时,重复使用strcat()
会涉及二次行为。此外,出于同样的原因,通常最好避免在循环条件中使用strlen()
;它(可能)在每次迭代中都会被评估,因此它也会导致二次行为
char a[100], b[100];
char *bp = b;
//Some code that puts a string into a
size_t len = strlen(a);
for (int i = 0; i < len; i++, bp++)
{
if (a[i] == 'C')
*bp = 'b';
else if(a[i] == 'O')
*bp = 'a';
else if(a[i] == 'D')
*bp = '1';
else
*bp = a[i];
}
*bp = '\0'; // Null-terminate the string
只要a
中的字符串足够短,就不会溢出b
。如果有时在b
中添加几个字符,则需要索引(i
和j
),或者可以在第一个版本中每个循环多次递增指针bp
,而且您需要确保不会溢出b
的边界,因为您希望将a
的子字符串正好取一个字符长:
strncat(b, a+i, 1);
你似乎对字符串感到困惑。字符串不仅仅是数组。你在读哪本书
当您第一次调用strcat对b
进行操作时,b
不一定是字符串。结果是未定义的行为。这段代码似乎在您的系统上正常运行,但如果它正常运行,那就是巧合。我见过类似的代码在其他系统上以奇怪的方式失败。像这样修复它:
char a[100], b[100];
//Some code that puts a string into a
a[x] = '\0'; // <--- Null terminator is required for a to contain a "string".
// Otherwise, you can't pass a to strlen.
for(i = 0; i<strlen(a); i++)
{
if(a[i] == 'C')
b[i] = 'b';
else if(a[i] == 'O')
b[i] = 'a';
else if(a[i] == 'D')
b[i] = '1';
else
b[i] = a[i];
}
b[i] = '\0'; // If you don't put a null character at the end, it isn't a string.
chara[100],b[100];
//将字符串放入
a[x]='\0';//如果实现可以证明a
中包含的字符串的长度没有改变,那么它可以进行与您手动进行的优化相同的优化。是的,但这是一个非常大的If。@jonathanLeffler:你说得对。假设实现可能从这段代码中产生什么行为是没有意义的。。。这与这个问题无关。因此,我现在的问题是:为什么要假设?@modifiablelvalue:我不确定你想得到什么?@JonathanLeffler如果你不准备排除实现可能不执行优化的可能性,那么你不能排除实现可能执行优化的可能性。你有没有研究过编译器每天进行的优化?此外,该循环的行为与此问题无关。这就是我要说的,为了避免像上次和Ben Voigt讨论那样陷入冗长、毫无意义的讨论中:/这是一个有效的观察,但它不能回答他的问题,这就是如何附加一个字符而不是整个以NUL结尾的字符串。@BenVoigt好的,我再次阅读了他的问题,并试图改进我的answer@BenVoigt当我们谈到谁对什么发表了不正确的评论时。。。您的答案不是附加了多个字符吗?@modifiablelvalue:my或Grijesh?我的最多追加一个,这就是strncat
中的n
所做的。@modifiablelvalue:它将字符串延长一个a[i]
替换现有的NUL字符,然后添加新的NUL字符。或者,你可以把它想象成移动NUL角色,我不在乎。无论哪种方式,字符串都是一个字符较长的,并且仍然有一个终止的NUL。考虑指针和包含翻译的表。user2204015以良好的格式发布您的问题,这样您就可以轻松理解您的问题。哈哈哈(和其他恶心的驴叫声)。我的意思是a[I]
。谢谢:)一些代码
char a[100], b[100];
//Some code that puts a string into a
size_t len = strlen(a);
for (int i = 0; i < len; i++)
{
if (a[i] == 'C')
b[i] = 'b';
else if(a[i] == 'O')
b[i] = 'a';
else if(a[i] == 'D')
b[i] = '1';
else
b[i] = a[i];
}
b[i] = '\0'; // Null-terminate the string
strncat(b, a+i, 1);
char a[100], b[100];
//Some code that puts a string into a
a[x] = '\0'; // <--- Null terminator is required for a to contain a "string".
// Otherwise, you can't pass a to strlen.
for(i = 0; i<strlen(a); i++)
{
if(a[i] == 'C')
b[i] = 'b';
else if(a[i] == 'O')
b[i] = 'a';
else if(a[i] == 'D')
b[i] = '1';
else
b[i] = a[i];
}
b[i] = '\0'; // If you don't put a null character at the end, it isn't a string.