C 在 void 函数中反转单个字符串中的两个单词
C reverse two words in a single string in a void function
我的函数应该反转两个字符串 - 名字和姓氏。所以 John Smith 的输出应该是 Smith John。问题是,它应该是 void 函数。所以我想应该修改全局数组。我试图对其进行编码 - 我附加了代码,但它不起作用。我的阵列保持不变。我认为结论的某个地方是错误的,我试图覆盖初始数组 'name' 作为结论,它不起作用。请问有什么错误的想法吗?
#include <stdio.h>
#include <string.h>
void reverse(char *name) {
int index = 0;
char first[20];
char second[20];
bool firstName = true;
for (int i = 0; i < strlen(name); i++) {
if (name[i] == ' ') {
firstName = false;
first[i] = '[=10=]';
}
else if (firstName)
first[i] = name[i];
else {
second[index] = name[i];
index++;
}
}
second[index] = ' ';
second[index+1] = '[=10=]';
name = strcat(second, first);
}
int main() {
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
}
Any idea about mistake please?
在 main 函数中,我们将 name 传递给 reverse() 这里 name 包含数组名称的地址[] 例如 P1。
reverse(name); // name is P1
在函数 reverse name 中将包含数组 name 的地址,即 P1
void reverse(char *name) { // name still p1
并且此名称是函数的局部名称。
这里,让我们先来了解一下strcat。
正如手册页所建议的那样:
char *strcat(char *dest, const char *src);
The strcat() function return a pointer to the resulting string dest.
如以下代码所示,我们正在更新 name。现在名称将包含指向目标字符串的指针,例如 p2。
name = strcat(second, first); // name has become p2
现在当我们 return 到 main() 时,name 仍然包含数组的地址,即 P1(函数上下文完成,局部变量也完成)而不是最终字符串的地址,即 P2.
reverse(name); // name is p1
printf("reversed: %s\n", name); // name is p1
你做错了什么?您未能 return 修改后的字符串。将 name = strcat(second, first);
替换为:
strcpy(name, second);
strcat(name, first);
这是一个非常简单的替代解决方案:
#include <stdio.h>
void reverse(char *buf) {
char first[20], last[20];
if (sscanf(buf, "%19s%19s", first, last) == 2) {
sprintf(buf, "%s %s", last, first);
}
}
int main() {
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
return 0;
}
中间缓冲区很无聊。这是一个没有大小限制的 char-by-char 交换器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void reverse(char *name) {
char c1, c2;
size_t pos1 = 0, pos2 = 0, pos_sep, name_len, count;
{
char *p_sep = strchr(name, ' ');
if (!p_sep) {
return;
}
pos_sep = p_sep - name;
name_len = pos_sep + strlen(p_sep);
}
c1 = name[0];
for (count = name_len; count != 0; count--) {
{
if (pos2 < pos_sep) {
pos2 = pos2 + name_len - pos_sep;
} else if (pos2 > pos_sep) {
pos2 = pos2 - (pos_sep + 1);
} else {
pos2 = name_len - (pos_sep + 1);
}
c2 = name[pos2];
name[pos2] = c1;
c1 = c2;
if (pos2 == pos1) {
pos1++;
pos2 = pos1;
c1 = name[pos1];
}
}
//fprintf(stderr, "%s\n", name);
}
}
static void _test(char *name, const char *expected) {
reverse(name);
if (0 != strcmp(expected, name)) {
fprintf(stderr, "something wrong\n");
exit(1);
}
}
#define test(name, expected) do { \
static char buf[] = name; \
_test(buf, expected); \
} while(0)
int main()
{
test("abc", "abc");
test("abcde 123", "123 abcde");
test("abc 12345", "12345 abc");
test("ab 12", "12 ab");
test("a 12", "12 a");
test("ab 1", "1 ab");
test("a ", " a");
test(" 1", "1 ");
test(" ", " ");
test("ab 123", "123 ab");
test("ab 12", " 12 ab");
test("abc 1234", "1234 abc");
test("abc 12345", "12345 abc");
test("abcd 1234", "1234 abcd");
test("abcd 12345", "12345 abcd");
fprintf(stderr, "all fine\n");
return 0;
}
以下建议代码:
- 干净地编译
- 消除不必要的局部变量
- 利用 C
的可变长度数组特性
- 执行所需的操作。
现在,建议的代码:
#include <stdio.h>
#include <string.h>
// prototypes
void reverse(char *name);
int main( void )
{
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
}
void reverse(char *name)
{
char genFirst[ strlen( name )+1 ];
char genSecond[ strlen( name )+1 ];
memset( genFirst, '[=10=]', strlen( name ) );
memset( genSecond, '[=10=]', strlen( name ) );
size_t i;
for ( i = 0; name[i] && name[i] != ' '; i++ )
{
genFirst[i] = name[i];
}
i++;
for ( size_t j = 0; name[j]; j++ )
{
genSecond[ j ] = name[ i+j ];
}
genSecond[i] = ' ';
strcpy( name, genSecond );
strcat( name, genFirst );
}
结果输出是:
originally: John Smith
reversed: Smith John
我的函数应该反转两个字符串 - 名字和姓氏。所以 John Smith 的输出应该是 Smith John。问题是,它应该是 void 函数。所以我想应该修改全局数组。我试图对其进行编码 - 我附加了代码,但它不起作用。我的阵列保持不变。我认为结论的某个地方是错误的,我试图覆盖初始数组 'name' 作为结论,它不起作用。请问有什么错误的想法吗?
#include <stdio.h>
#include <string.h>
void reverse(char *name) {
int index = 0;
char first[20];
char second[20];
bool firstName = true;
for (int i = 0; i < strlen(name); i++) {
if (name[i] == ' ') {
firstName = false;
first[i] = '[=10=]';
}
else if (firstName)
first[i] = name[i];
else {
second[index] = name[i];
index++;
}
}
second[index] = ' ';
second[index+1] = '[=10=]';
name = strcat(second, first);
}
int main() {
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
}
Any idea about mistake please?
在 main 函数中,我们将 name 传递给 reverse() 这里 name 包含数组名称的地址[] 例如 P1。
reverse(name); // name is P1
在函数 reverse name 中将包含数组 name 的地址,即 P1
void reverse(char *name) { // name still p1
并且此名称是函数的局部名称。
这里,让我们先来了解一下strcat。 正如手册页所建议的那样:
char *strcat(char *dest, const char *src);
The strcat() function return a pointer to the resulting string dest.
如以下代码所示,我们正在更新 name。现在名称将包含指向目标字符串的指针,例如 p2。
name = strcat(second, first); // name has become p2
现在当我们 return 到 main() 时,name 仍然包含数组的地址,即 P1(函数上下文完成,局部变量也完成)而不是最终字符串的地址,即 P2.
reverse(name); // name is p1
printf("reversed: %s\n", name); // name is p1
你做错了什么?您未能 return 修改后的字符串。将 name = strcat(second, first);
替换为:
strcpy(name, second);
strcat(name, first);
这是一个非常简单的替代解决方案:
#include <stdio.h>
void reverse(char *buf) {
char first[20], last[20];
if (sscanf(buf, "%19s%19s", first, last) == 2) {
sprintf(buf, "%s %s", last, first);
}
}
int main() {
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
return 0;
}
中间缓冲区很无聊。这是一个没有大小限制的 char-by-char 交换器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void reverse(char *name) {
char c1, c2;
size_t pos1 = 0, pos2 = 0, pos_sep, name_len, count;
{
char *p_sep = strchr(name, ' ');
if (!p_sep) {
return;
}
pos_sep = p_sep - name;
name_len = pos_sep + strlen(p_sep);
}
c1 = name[0];
for (count = name_len; count != 0; count--) {
{
if (pos2 < pos_sep) {
pos2 = pos2 + name_len - pos_sep;
} else if (pos2 > pos_sep) {
pos2 = pos2 - (pos_sep + 1);
} else {
pos2 = name_len - (pos_sep + 1);
}
c2 = name[pos2];
name[pos2] = c1;
c1 = c2;
if (pos2 == pos1) {
pos1++;
pos2 = pos1;
c1 = name[pos1];
}
}
//fprintf(stderr, "%s\n", name);
}
}
static void _test(char *name, const char *expected) {
reverse(name);
if (0 != strcmp(expected, name)) {
fprintf(stderr, "something wrong\n");
exit(1);
}
}
#define test(name, expected) do { \
static char buf[] = name; \
_test(buf, expected); \
} while(0)
int main()
{
test("abc", "abc");
test("abcde 123", "123 abcde");
test("abc 12345", "12345 abc");
test("ab 12", "12 ab");
test("a 12", "12 a");
test("ab 1", "1 ab");
test("a ", " a");
test(" 1", "1 ");
test(" ", " ");
test("ab 123", "123 ab");
test("ab 12", " 12 ab");
test("abc 1234", "1234 abc");
test("abc 12345", "12345 abc");
test("abcd 1234", "1234 abcd");
test("abcd 12345", "12345 abcd");
fprintf(stderr, "all fine\n");
return 0;
}
以下建议代码:
- 干净地编译
- 消除不必要的局部变量
- 利用 C 的可变长度数组特性
- 执行所需的操作。
现在,建议的代码:
#include <stdio.h>
#include <string.h>
// prototypes
void reverse(char *name);
int main( void )
{
char name[] = "John Smith";
printf("originally: %s\n", name);
reverse(name);
printf("reversed: %s\n", name);
}
void reverse(char *name)
{
char genFirst[ strlen( name )+1 ];
char genSecond[ strlen( name )+1 ];
memset( genFirst, '[=10=]', strlen( name ) );
memset( genSecond, '[=10=]', strlen( name ) );
size_t i;
for ( i = 0; name[i] && name[i] != ' '; i++ )
{
genFirst[i] = name[i];
}
i++;
for ( size_t j = 0; name[j]; j++ )
{
genSecond[ j ] = name[ i+j ];
}
genSecond[i] = ' ';
strcpy( name, genSecond );
strcat( name, genFirst );
}
结果输出是:
originally: John Smith
reversed: Smith John