如何使用gets()读取无符号字符数组?
Posted
技术标签:
【中文标题】如何使用gets()读取无符号字符数组?【英文标题】:How to read unsigned character array using gets()? 【发布时间】:2011-05-28 07:33:08 【问题描述】:我需要从输入中读取一些无符号字符(ASCII 值>127)。 所以我用了-
unsigned char S[102];
但是当我接受这样的输入时-
gets(S);
编译器显示错误:
错误:来自的无效转换 'unsigned char*' 到 'char*'
所以我的问题是如何使用 gets() 或任何其他函数读取无符号字符数组。
【问题讨论】:
最好的方法是永远不要在任何情况下使用gets
。如果有人拿着枪指着你的头说:“在你的代码中使用gets
”,你应该能够为了人类的更大利益而接受你的命运。
【参考方案1】:
首先,您不应该使用gets
。它不能在任何情况下都可以安全使用。为了幽默的效果,我的评论可能有点夸张,但重点仍然存在。
您应该使用而不是gets
的函数是fgets
。 fgets
采用 FILE *
指针(但您可能只想传递 stdin
)和最大长度,因此它知道不会溢出您的缓冲区。与gets
不同,fgets
不能保证读取整行——该行可能对于您的缓冲区来说太大而无法容纳。但是,您可以轻松地从中恢复并编写代码以以各种方式正确处理输入(而使用gets
,您只需要希望您的缓冲区足够长,如果不是,谁知道会发生什么。 )
我有点不清楚您打算阅读什么样的数据。如果是文本,fgets
可能就是您要查找的内容。它仍然需要char *
,所以要完成这项工作,您需要在将S
传递给函数时将其转换为char *
。通常强制转换是一件坏事,尤其是从有符号类型到无符号类型的强制转换,但在这种情况下(可能)不会发生任何坏事。
如果您实际上是在将二进制数据读入无符号数组,您应该查看fread
。与fgets
不同,它需要void *
来容纳您需要读取的任何类型的数据,因此不需要强制转换。请注意,fread
读取的是块而不是行,因此如果您想要文本输入,您应该查看其他地方 - 它不会尝试读取整行,也不会在看到行结束时停止读取缓冲区。
【讨论】:
感谢您的回答。但是 fgets() 可以将字符作为输入,其 ascii 值大于 127 意味着我需要无符号字符,因为 fgets((char ,) (int), (FILE *)),这里我看到它需要 char 输入,而不是 (unsigned char*)???? @russell - 如果大于 127,signed char *
(可能在您的平台上可能是 char *
)会将其解释为负数,但相同的二进制数据将写入您的数组,因此当您的数组将该模式解释为 unsigned
数据时,它们将是大于 127 的数字。试试这个:int main(void) unsigned short u = 65535, *up = u; /* signed */ short *sp = (short *)up, s = *sp; printf("Unsigned: %hu\nSigned: %hi\n", u, s); return 0;
所以,这意味着我不需要使用 unsigned char S[102];使用 char S[102] 就足够了吗?还能处理大于127的读、处理、写字符??
没有。 signed char *
将二进制 11111111
视为 -1。 unsigned char
将该二进制文件视为 255。如果您希望将数据解释为无符号,请使用无符号。只需知道,如果您必须将其作为签名类型传递给 fgets
,则底层二进制数据将按照您期望的方式工作。【参考方案2】:
您可以使用 gets
代替:
fgets (s, MAX_BUFFER, stdin);
scanf ("%[^\n]%*c", s);
当使用值大于 127 的 ASCII 字符时,两者都可以工作,例如:.±┼┤.▒⎽ .␍≤┼⎽≤└ .␍≤┼⎽├⎼ .±┼┤.┴␊⎼⎽␋⎺┼ .±┼┤.┴␊⎼⎽␋
gets
也会这样做。您不需要将数组作为unsigned char *
传递。
【讨论】:
谢谢。主要问题是 gets() 是否可以接受 ASCII>127 值字符。现在我知道它可以。但是当我们比较 2 个字符串(ASCII 值--> 0-255)使用 strcmp() 可以正确排序这两个字符串吗?? 您的scanf
示例同样糟糕,因为它不执行边界检查。 scanf
可以进行边界检查,但要为此目的正确使用 scanf
非常困难,而且很难从糟糕的情况中恢复,因此最好坚持使用 fgets
。以上是关于如何使用gets()读取无符号字符数组?的主要内容,如果未能解决你的问题,请参考以下文章