C 为什么末尾的连接字符串与代码的功能完全不同?

C 为什么末尾的连接字符串与代码的功能完全不同?,c,pdflatex,C,Pdflatex,下面的代码看起来可能很大,但实际上很简单。我想用C制作一个练习生成器,它连接latex格式的字符串,存储在函数本地数组中 但是输出完全不是我所期望的。我可能做了一些错误的指针,或一些溢出的地方 尝试了我在互联网上能找到的所有技巧: (1) 在位置0处用“\0”初始化字符串; (2) 使用指向字符串的指针传递给函数 int-create\u-exercise\u字符串(字符**s,int-s\u大小){ //演习形式为x+n=m; //ASCII 48-57='0'…'9'; int-exerci

下面的代码看起来可能很大,但实际上很简单。我想用C制作一个练习生成器,它连接latex格式的字符串,存储在函数本地数组中

但是输出完全不是我所期望的。我可能做了一些错误的指针,或一些溢出的地方

尝试了我在互联网上能找到的所有技巧:

(1) 在位置0处用“\0”初始化字符串; (2) 使用指向字符串的指针传递给函数

int-create\u-exercise\u字符串(字符**s,int-s\u大小){
//演习形式为x+n=m;
//ASCII 48-57='0'…'9';
int-exercises_左=10;
char*运动;
字符操作\u list[][2]={“+\0”,“-\0”};
char equal[]=“&=&”;//&用于以乳胶中包含的项目为中心;
字符数组\u begin[]=“\\begin{eqnarray*}\n”;
字符数组_end[]=“\\end{eqnarray*}”;
字符数[1];
strcat(*s,数组_begin);
s_size-=strlen(数组_开始);
//除去
看跌期权(“在产生行使权之前”);
while(练习左>0和s大小>0){
运动=马洛克(256);
如果(!练习){
puts(“分配错误,退出…”);
getchar();
出口(1);
}
练习[0]='\0';
//感兴趣的部分=================================================
如果(左<10)
strcat(练习);
printf(“练习编号%d\n”,左练习);
strcpy(练习,“x”);
//添加一个操作符
strcat(练习、操作列表[rand()%2]);
//加号
数字[0]=(rand()%10)+48;
strcat(练习、编号);
//加一个相等的
strcat(运动,同等);
//加号
数字[0]=(rand()%10)+48;
strcat(练习、编号);
//结束=================================================================
s_size-=strlen(练习);
strcat(*s,练习);
自由(运动);
练习左——;
}
//除去
看跌期权(“行权产生结束”);
if(s_大小
我希望输出是这样的

\begin{eqnarray*}
x-9&=&3\\
x+3&=&12\\
x-2&=&3\\
... 7 other exercises
\end{eqnarray*}
但实际上我得到了

\begin{eqnarray*}
x-5\end{eqnarray*}&=&9\end{eqnarray*}x-9\end{eqnarray*}&=&2\end{eqnarray*}x+3\end{eqnarray*}&=&1\end{eqnarray*}x-7\end{eqnarray*}&=&0\end{eqnarray*}x+6\end{eqnarray*}&=&1\end{eqnarray*}x-6\end{eqnarray*}&=&5\end{eqnarray*}x+6\end{eqnarray*}&=&8\end{eqnarray*}x-8\end{eqnarray*}&=&6\end{eqnarray*}x+4\end{eqnarray*}&=&5\end{eqnarray*}x+1\end{eqnarray*}&=&5\end{eqnarray*}\end{eqnarray*}
没有\n整体添加,并且重复添加了一些\end{eqnarray*}

怎么了?

我设法把它修好了

我所能说的是,在处理字符串时,请始终记住是否添加了终止字符,因此在我的例子中,我需要加强对C中字符串分配的研究

问题在于变量编号[1]

number[0] = rand() % 10 + 48;
此代码添加ASCII中0和9[48,57]之间数字的字符表示形式

但它不会添加终止空字符

每次我将
number
连接到
exercise
字符串时,它都会溢出到另一个具有终止空字符的局部变量,因此
strcat()
的“未定义行为”是它一直在读取另一个局部变量

幸运的是,内存中有一个“\0”雷区,否则如果试图读取受保护的内存,我就需要把头撞到墙上


谢谢你的帮助

对于一个
字符编号[1]
应该是
字符编号[2]
——空字符串终止符总是需要一个字节。
练习[0]='\0'
我认为这也有问题,由于之前会遇到空字符,因此将连接到字符串末尾的内容将被忽略。@Gasperstukej它应将“\0”替换为附加字符串的初始字符。。。某个地方缺少一个“\0”,我正在尝试找出它。strcat()应该总是向字符串追加一个终止null,问题应该是我声明了一些字符串的方式。。。可能引用其中一个字符串时没有终止null,而这个字符串正好在\end{enqarray*}之前,所以它会被再次写入,并且在这个字符串的末尾肯定有一个“\0”。。。现在我还需要理解为什么没有附加\n。我不得不说我的编码有点乱!。。。将数字写入
数字[0]
后,还需要nul终止已更正的
字符编号[2]
。如果在所有字符串上都没有终止符,则不能使用
strcat()
,默认情况下它不存在。