首先,此代码段不适用于生产代码。所以,请不要讲它“不安全”。谢谢!
因此,以下代码是解析器的一部分,它接受csv并使用它来填充sqlite3数据库。当编译并在Snow Leopard中运行时,它运行得很好。现在我已切换到Lion,scanf语句抛出总线错误:10。具体来说,它似乎与我如何消费并丢弃每行末尾的'\ n'有关:
int main()
{
sqlite3* db;
sqlite3_open("someExistingDB.sqlite3", &db);
FILE *pFile;
pFile = fopen("excelData.csv","r");
char name[256],country[256], last[256], first[256], photoURI[256];
char sqlStatement[16384];
while(fscanf(pFile, "%[^,],%[^,],%[^,],%[^,],%[^\n]%*c", name, country, last,first, photoURI) != EOF)
{
blah...
...
如果我删除最后一个%* c,这意味着使用'\ n'并忽略它以便前进到下一行,程序不会崩溃。但当然解析不正确。
另外,请注意,EOF似乎不是问题;我也试过一个fscanf语句,而不是上面显示的while循环。
有什么想法吗?
编辑:让我补充一点,代码最初编译并运行在带有Snow Leopard的intel core duo(32位)macbook中,现在我正在编译它并在Lion上运行MacPro(64位)。所以我想知道它是否与对齐有关?答案 0 :(得分:1)
有趣。总线错误通常是由于对齐问题造成的,但这可能并非如此,因为您扫描的所有内容都是char
。
这将允许您做两件事:
fgets
之前打印出调试语句中的行(或者在扫描之后,如果预期的转换计数错误),那么你可以看看是否有任何问题;和sscanf
对齐,因为sscanf
已经很好地完成了此工作。所以它会像(未经测试的):
fscanf
您还应该检查fgets
和char bigHonkinBuffer[16384];
while (fgets (bigHonkinBuffer, sizeof(bigHonkinBuffer), pFile) != NULL) {
if (sscanf(bigHonkinBuffer, "%[^,],%[^,],%[^,],%[^,],%[^\n]", name, country, last,first, photoURI) != 5) {
// printf ("Not scanned properly: [%s]\n", bigHonkinBuffer);
exit (1);
}
}
来电的返回值,如果这超过“播放”代码(即,如果这些文件可能不存在,则最轻微)
答案 1 :(得分:1)
我在使用XCode 4运行Lion(10.7.1)的Mac Mini上尝试了以下代码修改。
#include <stdio.h>
static void print(const char *tag, const char *str)
{
printf("%8s: <<%s>>\n", tag, str);
}
int main(void)
{
FILE *pFile = fopen("excelData.csv","r");
char name[256], country[256], last[256], first[256], photoURI[256];
while (fscanf(pFile, "%[^,],%[^,],%[^,],%[^,],%[^\n]%*c",
name, country, last, first, photoURI) == 5)
{
print("name", name);
print("country", country);
print("last", last);
print("first", first);
print("photoURI", photoURI);
}
return 0;
}
我使用以下方法生成了64位二进制文件:
gcc -O -std=c99 -Wall -Wextra xxx.c -o xxx
没有任何警告。给定输入数据:
Monster,United States,Smith,John,http://www.example.com/photo1
Emancipated Majority,Canada,Jones,Alan,http://www.example.com/photo2
A Much Longer Name Than Any Before,A Land from Far Away and In the Imagination Most Beautiful,OneOfTheLongerFamilyNamesYou'llEverSee,ALongishGivenName,http://www.example.com/photo3/elephant/pygmalion/photo3,x31
它产生输出:
name: <<Monster>>
country: <<United States>>
last: <<Smith>>
first: <<John>>
photoURI: <<http://www.example.com/photo1>>
name: <<Emancipated Majority>>
country: <<Canada>>
last: <<Jones>>
first: <<Alan>>
photoURI: <<http://www.example.com/photo2>>
name: <<A Much Longer Name Than Any Before>>
country: <<A Land from Far Away and In the Imagination Most Beautiful>>
last: <<OneOfTheLongerFamilyNamesYou'llEverSee>>
first: <<ALongishGivenName>>
photoURI: <<http://www.example.com/photo3/elephant/pygmalion/photo3,x31>>
!= EOF
vs == 5
更改与示例数据无关,但一般来说可能更强大。最后一行数据利用您对模式的更改,并在“最后一个字段”中包含一个逗号。
由于您的代码没有检查文件是否正确打开,我不得不怀疑这是否是您的问题,尽管这更可能产生分段违规而不是总线错误。
所以,没有回答你的问题 - 但有些代码供你试用。