我对C语言比较陌生,所以任何帮助我理解正在发生的事情都是很棒的!!!
我有一个名为Token
的结构体,如下所示:
//Token struct
struct Token {
char type[16];
char value[1024];
};
我正在尝试读取文件并将从文件读取的字符追加到Token.value
中,如下所示:
struct Token newToken;
char ch;
ch = fgetc(file);
strncat(newToken.value, &ch, 1);
这很有效!
我的问题是Token.value
以几个我不理解的值开始,在我追加的字符之前。当我将newToken.value
的结果打印到控制台时,我得到@�����TheCharactersIWantedToAppend
。我可能会想出一个创可贴解决方案来追溯删除或处理这些字符,但如果没有必要,我宁愿不这样做。
在分析字符时,我将它们视为(按索引1-5的顺序):\330, \377, \377, \377, \177
。我读到\377
在C中是EOF
的特殊字符,但在十进制中也是255?这些值是否构成内存地址?我是否通过在strncat
中使用&ch
将地址添加到newToken.value
?如果是,我如何防止它们进入newToken.value
?
**注意:**如果我使用strncat(newToken.value, ch, 1)
而不是strncat(newToken.value, &ch, 1)
(ch与&ch),我会得到一个分段错误。
2条答案
按热度按时间iqxoj9l91#
我将努力巩固评论中已经给出的答案。
这个版本的代码使用了
strncat()
,和你的一样,但是解决了Nick(我们必须初始化目标)和Dúthomhas(strncat()
的第二个参数必须是字符串,而不是指向单个字符的指针)指出的问题(是的,“string”实际上是char[]
,传递给函数的值是char*
;但它必须指向至少两个字符的数组 ,最后一个字符包含'\0'
。)请注意,
strncat()
,strncpy()
和所有相关函数都很复杂。它们不会写入超过N个字符。但是strncpy()
只会在源字符串的少于个字符时将最后的'\0'
添加到目标字符串;并且strncat()
***总是**添加它,即使它源具有正好N个字符或更多(编辑;谢谢,@Clifford)。另一个版本使用了一个
index
变量,将每个字符直接写入目标字符串的“当前”位置,而没有使用strncat()
。我认为它更简单、更安全,因为它没有混淆单个字符和字符串的语义。Edited:
fgetc()
返回一个int
,我们应该在将其转换为char
之前检查EOF *(谢谢,@chqrlie)。wrrgggsh2#
您正在追加未初始化的字符串,因此可以包含 anything。字符串的结尾由NUL(0)字符指示,在您的示例中,6个字节后碰巧有一个,但
value
数组中不需要任何,因此代码存在严重缺陷,并将导致不确定性行为。您需要将
newToken
示例初始化为空字符串。例如:或者零初始化整个结构:
关键是C没有显式的初始化器就不会初始化非静态对象。
此外,使用
strncat()
的效率非常低,而且执行时间不确定,这取决于目标字符串的长度(请参见https://www.joelonsoftware.com/2001/12/11/back-to-basics/)。在这种情况下,最好维护添加的字符数的计数,并将字符和终止符直接写入数组。例如: