我要反转字符串中的单词。我觉得自己正朝着正确的方向前进。但我一直得到不稳定的输出并且无法帮助,但认为它与我的strncat()
函数有关。你有没有看到任何问题,我决定处理它。我对其他方法的建议持开放态度。
int main()
{
int ch, ss=0, s=0;
char x[3];
char *word, string1[100], string2[100], temp[100];
x[0]='y';
while(x[0]=='y'||x[0]=='Y')
{
printf("Enter a String: ");
fgets(string1, 100, stdin);
if (string1[98] != '\n' && string1[99] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
word = strtok(string1, " ");
while(word != NULL)
{
s = strlen(word);
ss=ss+s;
strncpy(string2, word, s);
strncat(string2, temp, ss);
strncpy(temp, string2, ss);
printf("string2: %s\n",string2);
printf("temp: %s\n",temp);
word = strtok(NULL, " ");
}
printf("Run Again?(y/n):");
fgets(x, 2, stdin);
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
}
return 0;
}
这是我的输出:
Enter a String: AAA BBB CCC DDD EEE
string2: AAA
temp: AAA
string2: BBBAAA
temp: BBBAAA
string2: CCCAAABBBAAA
temp: CCCAAABBB
string2: DDDAAABBBAAACCCAAABBB
temp: DDDAAABBBAAA
string2: EEE
AABBBAAACCCAAABBBDDDAAABBBAAA
temp: EEE
AABBBAAACCCA
答案 0 :(得分:1)
您需要初始化" 至少" strcat()
个参数的第一个字节,因为它希望它的参数被nul
终止,所以
string2[0] = '\0';
会有所帮助,但您第一次不需要strcat()
,而是可以使用strcpy()
。
答案 1 :(得分:0)
您未在strncpy
来电中复制足够的字符。
从手册页:
strncpy()函数类似,但不超过n个字节 src的副本被复制。因此,如果前n个中没有空字节 src的字节,结果不会以空值终止。
由于您指定了字符串的确切长度,因此不会附加NULL终止字节。
您需要为每个添加1:
strncpy(string2, word, s+1);
strncat(string2, temp, ss); // strncat always NULL terminates
strncpy(temp, string2, ss+1);
输出:
Enter a String: aaa bbb ccc ddd eee
string2: aaa
temp: aaa
string2: bbbaaa
temp: bbbaaa
string2: cccbbbaaa
temp: cccbbbaaa
string2: dddcccbbbaaa
temp: dddcccbbbaaa
string2: eee
dddcccbbbaaa
temp: eee
dddcccbbbaaa
最后一次迭代的分割线是因为fgets
将换行符留在缓冲区的末尾。您可以在分隔符列表中将\n
包含到strtok
:
word = strtok(string1, " \n");
...
word = strtok(NULL, " \n");
答案 2 :(得分:0)
确定您是否真的尝试:
相当困难反转字符串中的单词
或反转字符串。
如果你只是试图反转整个字符串,那么将字符串分成标记是没有多大意义的,当你需要做的只是以相反的顺序写原文时。
以表面值的形式提出您的请求,可能更容易简单地使用开始指针'p'
和结束指针'ep'
向下走,并在找到时反转两个指针之间的内容带有space
的{{1}}。换句话说,降低原始字符串的新副本,并使用'ep'
指向每个单词的开头,当'p'
指向该单词末尾的空格(或字符串结尾)时,只需反转字符就地即可。这将消除所有复制和连接。
一种在原地反转字符的方法是:
'ep'
<强>输出强>
#include <stdio.h>
#include <string.h>
void strprev (char *begin, char *end);
int main (int argc, char **argv) {
if (argc < 2) return 1;
size_t len = strlen (argv[1]);
char *p, *ep;
char rev[len + 1]; /* a VLA is fine here */
strncpy (rev, argv[1], len + 1); /* copy string to rev */
p = ep = rev;
for (;;) { /* for every char in rev */
if (*ep && *ep != '\n') { /* if not at end of rev, and */
if (*ep == ' ' && ep > p) { /* if ' ' and chars between */
strprev (p, ep - 1); /* reverse between p and ep */
p = ep + 1; /* advance p to next word */
}
}
else { /* handle last word in rev */
if (ep > p)
strprev (p, ep - 1);
break;
}
ep++;
}
printf ("\n string : %s\n reverse : %s\n\n", argv[1], rev);
return 0;
}
/** strprev - reverse string given by begin and end pointers.
* Takes valid string and swaps src & dest each iteration.
* The original string is not preserved.
* If str is not valid, no action taken.
*/
void strprev (char *begin, char *end)
{
char tmp;
if (!begin || !end) {
printf ("%s() error: invalid begin or end\n", __func__);
return;
}
while (end > begin)
{
tmp = *end;
*end-- = *begin;
*begin++ = tmp;
}
}
注意:如果您需要处理(跳过)单词之间的多个空格,则需要在上面的代码中指定$ ./bin/strrevex_a "ABC DEF GHI JKL MNO"
string : ABC DEF GHI JKL MNO
reverse : CBA FED IHG LKJ ONM
之前跳过它们。
如果你实际上试图反转整个字符串,那就容易多了。让我知道哪一个是正确的目标,如果需要,我会进一步帮助。