编译错误:程序中出现了杂散的 '\302',等等。

39

我在编译以下漏洞代码时遇到了问题:

http://downloads.securityfocus.com/vulnerabilities/exploits/59846-1.c

我正在使用"gcc file.c""gcc -O2 file.c",但两者都导致以下错误:
sorbolinux-exec.c: In function ‘sc’:
sorbolinux-exec.c:76: error: stray ‘\302’ in program
sorbolinux-exec.c:76: error: stray ‘\244’ in program
sorbolinux-exec.c:76: error: ‘t’ undeclared (first use in this function)
sorbolinux-exec.c:76: error: (Each undeclared identifier is reported only  once
sorbolinux-exec.c:76: error: for each function it appears in.)

我尝试在Kali LinuxUbuntu 10.04(Lucid Lynx)上编译它们,结果相同。

听起来像是你的文件包含了在标识符中不合法的“国家”字符之类的内容。但你真的应该在问题中包含出现错误的那些行。 - Hot Licks
错误信息说得很清楚。 - this
3
"\302\244" 是 UTF-8 序列 0xC2 0xA4 的八进制表示,代表货币符号:"¤"。 - Codo
2
这个问题是关于从网页、PDF文档或通过聊天(如Skype聊天或Facebook Messenger)复制粘贴代码时经常遇到的杂散字符问题的规范问题。因此,它值得得到全面的回答。目前,只有twitchdotcom slash KANJICODER的答案符合要求。 - Peter Mortensen
一个常见的问题是偏离了 ‘\342’ ‘\200’ ‘\213’(八进制数 - UTF-8 字节序列 0xE2 0x80 0x8B,Unicode 代码点 U+200B(零宽空格))。在 Geany 中使用正则表达式模式中的搜索 / 替换 \x{200B} 可以解决这个问题。 - Peter Mortensen
显示剩余19条评论
12个回答

27

您在该行中有一个无效字符。我看到的是这样的:

输入图像描述


谢谢,但这只消除了2行错误,这些错误仍然存在。raw.c: 在函数'sc'中: raw.c:76: 错误:未声明't'(在此函数中首次使用) raw.c:76: 错误:(每个未声明的标识符仅报告一次 raw.c:76: 错误:对于它出现的每个函数。) - Ahmed Taher
1
@AhmedTaher:这个修复确实解决了你问题中的错误信息。如果还有其他错误,请将它们添加到你的问题中。 - Codo
5
最有可能需要更改的代码是 uint64_t *p = (void *) ¤t[i];,应该改成 uint64_t *p = (void *) &current[i];。(¤ 是货币符号的 HTML 实体编码,应替换为实际的变量名。) - Codo
如果您从代码中删除货币符号,这些错误消息就不会再产生。这是完全不可能的。 - Codo
1
真正的解释是,浏览器曾经在处理具有许多错误的糟糕HTML代码的能力上进行了很多竞争。当OP的浏览器显示代码示例时,它看到了以“&”开头、以分号结尾的一系列字符,这些字符并不完全匹配HTML实体,但很接近,于是它决定进行替换,但同时也显示了额外的文本...这是浏览器的HTML解析错误,因为它试图过于协助。 - Theodore Murdock
显示剩余2条评论

18

你的源代码中存在无效字符。如果你的源代码中没有任何有效的非ASCII字符,可能是在双引号字符串文字中,那么你可以通过以下方式将文件转换为ASCII格式:

tr -cd '\11\12\15\40-\176' < old.c > new.c

使用iconv方法会在遇到无意义的字符时停止转换。上述命令行可用于处理示例文件。


5
当然,将文件转换为ASCII并清除所有Unicode字符。 这可能会起作用... 但是...
  1. 你不会知道自己修复了什么。
  2. 它还会破坏任何Unicode注释。例如://: A²+B²=C²
  3. 它有可能破坏明显的逻辑,并且代码仍然无法正常工作, 但解决方案不太明显。 例如:一个带有“智能引号”(“&”)的字符串或一个带有全角星号(*)的指针。现在,“SOME_THING”看起来像一个#define(SOME_THING),而*SomeType是错误的类型(SomeType)。

另外两种解决问题的方法:

  1. 更改字体以查看字符。(它可能在当前字体中不可见)

  2. 正则表达式搜索所有不属于非扩展ASCII字符集的Unicode字符。

    Notepad++中,我可以搜索到FFFF,它从未让我失望过。

    [\x{80}-\x{FFFF}]

    80是128的十六进制,是第一个扩展的ASCII字符。

    在点击“查找下一个”并突出显示似乎是空格后,您可以关闭搜索对话框并按Ctrl + C复制到剪贴板。

    然后将字符粘贴到Unicode搜索工具中。 我通常使用在线工具。 http://unicode.scarfboy.com/

例如:

我的代码中有一个项目符号(•)。 Unicode值为2022(十六进制),但由编译器读取为ASCII时, 你会得到\342 \200 \242(3个八进制值)。将每个八进制值转换为十六进制并将它们粘合在一起并不简单。因此,“E2 80 A2”不是你代码中的十六进制Unicode点。


是的,这种全面性的答案应该成为最高投票和被接受的答案。 - Peter Mortensen
1
或者,只需搜索/替换有问题的字符。例如,使用\x{200B}(错误偏离‘\342’ ‘\200’ ‘\213’)。在从网页复制代码后,我尝试了这种方法并行之有效。 - Peter Mortensen
一篇关于类似问题的详细回答(针对Linux)。 - Peter Mortensen
1
查找这些八进制UTF-8代码对应的字符,请访问以下链接:http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=%C2%B0&mode=char - markling
QMK网页出了问题。备用地址。但是我无法在新位置上重现这个问题。也许他们收到了太多的投诉并修复了它? - Peter Mortensen

4

我遇到了同样的问题,字符显示为星号,但实际上是一个UTF-8序列:

Encoder * st;

编译完成后,返回以下结果:
g.c:2:1: error: stray ‘\342’ in program
g.c:2:1: error: stray ‘\210’ in program
g.c:2:1: error: stray ‘\227’ in program

342 210 227是UTF-8编码的星号运算符(Unicode码点U+2217)。

删除“*”并重新输入即可解决问题。


稍微更直接的分析是 226 136 151(八进制)→ 0xE2 0x88 0x97(十六进制)→ Unicode 代码点 U+2217(ASTERISK OPERATOR)的 UTF-8 序列。 - Peter Mortensen
或者在支持正则表达式和Unicode的文本编辑器(例如GeanyNotepad++UltraEdit)中搜索/替换\x{2217} - Peter Mortensen
应该是: "...342 210 227(八进制)→0xE2 0x88 0x97(十六进制)..." (十进制数值正确,但与错误信息中的八进制数字不匹配)。 - Peter Mortensen

2
每当编译器发现一个特殊字符时,它会产生这种编译错误。我发现的错误如下:
错误:程序中的偏移 '\302' 和 错误:程序中的偏移 '\240'。

....

这是我从聊天软件中复制的一段代码。在 Facebook Messenger 中它只是一个特殊字符。但是当我将其复制到 Vim 编辑器中时,它才变成了正确的字符。但是编译器出现了上面的错误...然后,我手动写了那个语句后,问题得到了解决... :)

2
也许是因为你从互联网上复制了代码(来自一个可能不是ASCII编码页面而是UTF-8编码页面的站点),所以你可以将代码从这个站点转换为ASCII编码:
"http://www.percederberg.net/tools/text_converter.html"
在那里,你可以手动将其转换回UTF-8并检测错误,或者自动将其转换为ASCII并删除所有杂散字符。

是的,那是非常普遍的情况。网页代码中常见的有EN DASHEM DASHMINUS SIGN(不同于ASCII字符 - UTF-8序列0xE2 0x88 0x92)。它们可以在支持正则表达式的文本编辑器中通过\x{2013}\x{2014}\x{2212}进行搜索/替换。 - Peter Mortensen

1
这个问题出现的原因可能是你从一个HTML页面复制了一些文本,或者在Windows环境下进行修改,然后尝试在Unix/Solaris环境中编译。请使用“dos2unix”命令从文件中删除特殊字符:
dos2unix fileName.ext fileName.ext

1

您的代码中存在无效字符

这是一种常见的复制粘贴错误,特别是当代码从Microsoft Word文档或PDF文件中复制时。


0

我注意到在使用上述的tr命令时存在问题。tr命令完全删除了“智能引号”。最好是用类似以下的内容替换“智能引号”

这将为您提供将要被替换的快速预览。

sed s/[”“]/'"'/g File.txt

这将进行替换并将替换内容放入名为WithoutSmartQuotes.txt的新文件中。

sed s/[”“]/'"'/g File.txt > WithoutSmartQuotes.txt

这将覆盖原始文件。

sed -i ".bk" s/[”“]/'"'/g File.txt

http://developmentality.wordpress.com/2010/10/11/how-to-remove-smart-quotes-from-a-text-file/


但是这些工具不需要支持Unicode才能正常工作吗(至少在一般情况下)?它们支持吗? - Peter Mortensen

0
这里给出的解释是正确的。我只想补充一点,这个问题可能是因为你从某个地方复制了代码,比如一个网站或PDF文件,导致代码中有一些无效字符。
尝试找到那些无效字符,或者如果找不到就重新输入代码。那么它肯定会编译通过。
来源:stray error reason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接