我的问题基本上是使用printf打印一个char数组。
在某些情况下,它会打印出结果:
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
printf("The input: %s\n", orig);
printf("The output: %s\n", reArrange(orig));
return (EXIT_SUCCESS);
}
有时不会:
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
printf("%s\n", reArrange(orig));
return (EXIT_SUCCESS);
}
这是完整的代码(包括主要功能):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUBJECT '$'
#define ACTION '@'
#define OBJECT '?'
#define END '#'
char* reArrange(char* orig) {
int origSize = strlen(orig);
char subject[origSize], action[origSize], object[origSize];
//int i;
//for(i = 0; i < origSize; i++) {
// subject[i] = ' ';
// action[i] = ' ';
// object[i] = ' ';
//}
int subjectIndex = 0, actionIndex = 0, objectIndex = 0;
int timesEndCharShowUp = 0;
char state;
int i;
for(i = 0; i < origSize; i++) {
char ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
else if(ch == ACTION) {
state = ACTION;
}
else if(ch == OBJECT) {
state = OBJECT;
}
else if(ch == END) {
if(timesEndCharShowUp == 3) {
break;
}
else {
timesEndCharShowUp++;
}
}
else {
if(state == SUBJECT) {
subject[subjectIndex++] = ch;
}
else if(state == ACTION) {
action[actionIndex++] = ch;
}
else if(state == OBJECT) {
object[objectIndex++] = ch;
}
}
}
subject[subjectIndex] = '\0';
action[actionIndex] = '\0';
object[objectIndex] = '\0';
char rearranged[origSize];
sprintf(rearranged, "%s %s %s.\0", subject, action, object);
//printf("%s\n", rearranged);
orig = rearranged;
return orig;
}
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
// printf("The input: %s\n", orig);
// printf("The output: %s\n", reArrange(orig));
printf("result: ");
printf("%s\n", reArrange(orig) );
//fflush(stdout);
return (EXIT_SUCCESS);
}
答案 0 :(得分:5)
您正在返回指向驻留在堆栈中的内存的指针。封闭函数(rearranged
)返回后,reArrange
不可用,并且可能包含垃圾。
您可能需要malloc
rearranged
或全局声明。
答案 1 :(得分:3)
make char *
不是仅返回reArrange()
,而是接受可以写入结果的缓冲区。现在调用者必须为您的函数提供合适的缓冲区,并且您不再需要内存管理。你只是strncpy()安排到缓冲区。为了确保缓冲区足够大,用户还应该在第三个参数中提供缓冲区的大小:
char *rArrange(char *orig, char *result, int resultSize)
{
if (!result || resultSize == 0)
return NULL;
/* your code here */
strncpy(result, arranged, resultSize);
return result;
}
存储结果的替代malloc()
不是非常用户友好的(用户必须freemem()缓冲区但可能不知道这一点)。使用静态/全局缓冲区不是非常线程安全的。
答案 2 :(得分:1)
问题是你的函数reArrange
返回一个指向它不再控制的内存的指针。返回rearranged
数组的地址。返回发生后,此数组实际上不再存在 - 内存可以并且将被重用。
修复错误的快速黑客攻击是将rearranged
声明为static
。长期解决方法是使用malloc()
或等效的方法了解C的工作原理和代码。
答案 3 :(得分:1)
使用char rearranged[origSize];
创建了一个新的字符数组,该数组在reArrange
终止后超出范围。因此,在reArrange
的生命周期中,rearranged
是一个指向有意义的东西的指针;因此,orig = rearranged
是有道理的。
但是一旦它超出范围,reArrange(orig)
会返回指向rearranged
的指针,这是一个悬空指针,现在rearranged
不再存在。
答案 4 :(得分:1)
您的功能需要两个参数:
char* reArrange(char* orig)
应该是:
char* reArrange(char *rearragned, char* orig) {
// make your magic here!
}
呼叫序列:
char input[SIZE];
char rearrange [SIZE];
// initialize everything! Don't forget to rearrange[0] ='\0\;!!!
rearrange(rearranged, input);
// do you printing....
您还应该学习如何正确使用指针并查找“切换”。
答案 5 :(得分:0)
您确定代码的以下部分有效吗?
char* reArrange(char* orig) {
int origSize = strlen(orig);
char subject[origSize], action[origSize], object[origSize];
我的意思是origSize
必须是const
,它不能是动态值。您应该使用malloc
为subject , action and object
分配快照。
此外,您可以考虑一些指导原则:
1而不是:
for(i = 0; i < origSize; i++) {
char ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
你可以:
char ch;//declare char ch outside for loop
for(i = 0; i < origSize; i++) {
ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
2您可能希望使用switch
语句而不是if
语句,这会使您的代码看起来很棒。