某些运行时的sprintf()处理%s扩展ASCII(ISO 8859-1)?

时间:2016-01-28 15:22:40

标签: android c ansi-c

我在我的C应用程序中使用ISO 8859-1(拉丁语扩展ASCII字符集)。当我strcpy / strcat字符串的各个部分在一起时,它可以正常工作。但是当我在某些运行时(特别是Android的某些版本)上使用sprintf("%s %s")时,字符串将在扩展的ASCII字符(特别是é,尽管我没有尝试过其他人)被截断时被截断。< / p>

我认为%s只是复制字节,直到'\0'被击中。我怀疑strcpy / strcat是有效的,因为它确实可以做到这一点,没有任何格式化。可能会发生什么?

我应该注意到我没有使用printf()查看文本,而是使用我自己的文本渲染引擎来处理ISO-8859-1就好了。

更新: 为了澄清,我有一个NDK应用程序,它将字符串保存在C中,并将其传递给我的基于OpenGL的文本呈现引擎。如果我将完整的字符串作为char * literal传递,它显示正常。如果我将这些部分一起sprintf(),它会在é字符处被截断。 例如:

char buffer[1024];
strcpy(buffer, "This is ");
strcat(buffer, "the string I want to diésplay.");

显示罚款。但是这个:

sprintf(buffer, "%s%s", "This is ", "the string I want to diésplay.");

打印为:

This is the string I want to di

1 个答案:

答案 0 :(得分:1)

s[n]printf()的行为的指定方式与strcpy()strcat()等字符串操作函数的行为不同。当呈现相同的格式和打印项时,printf - 族函数都需要生成相同的字节序列。唯一的区别在于发送这些字节的位置。因此,如果构建C库使得它在通过printf()打印到标准流时对字符串数据(可能是代码转换)执行转换,那么当通过{{打印到字符串时,它将执行相同的转换1}}。

&#34; f&#34;在&#34; printf&#34;用于&#34;格式化#34;。标准既不表示也不暗示格式化字符串必须意味着将其字节逐字地转储到输出,因此转码或其他转换(例如我上面假设的)并非不可能。实际上,the docs for some versions of these functions表示区域设置依赖(&#34;请注意,生成的字符串的长度取决于区域设置并且难以预测&#34;),因此特别是转码是一种真正的可能性。

您描述的第三方观察的任何具体解释都必然是推测性的,因为您没有提供足够的代码或数据来进行自信的诊断。我倾向于怀疑在一个语言环境中运行程序的问题,该语言环境使用的字符编码与程序内部使用的字符编码不同。如果是这样,那么您可以通过改变运行的语言环境来本地重现问题,并且您可以通过确保程序始终以合适的语言环境运行的某种方式来解决问题。除此之外,您可以使用sprintf()getlocale()函数来提供帮助,特别是如果您想限制进行区域设置控制的范围。

因为最终你只依赖于printf-family函数来进行字符串操作,所以我认为最好使用问题中提供的解决方法:尽可能使用C&C的专用字符串操作函数,例如setlocale()strcpy(),用于执行字符串构建。由于您不依赖于实际输出的stdio函数,因此应该没问题。