我有一个vb6程序,它从sql server读取数据并将它们写入文本文件。每个记录由换行符分隔。 必须在sqlite数据库中读取和写入这些文件(也可以是> 200mb)。 为避免内存警告,我在C
中使用此功能读取文件的每一行“strRet”是在C
中读取的字符串“NSString * stringa”是转换为NSString
的字符串C.NSDictionary *readLineAsNSString(FILE *f,int pospass,BOOL testata,int primorecord )
{
char *strRet = malloc(BUFSIZ);//(char *) togliere perche con c potrebbe restituire un int
if (strRet==NULL)
{
return nil;
}
int size = BUFSIZ;
BOOL finito=NO;
int pos = 0;
int c;
fseek(f,pospass,SEEK_SET);
do{ // read one line
c = fgetc(f);
if (pos >= size-1)
{
size=size+BUFSIZ;
strRet = realloc(strRet, size);
if (strRet==NULL)
{
return nil;
}
}
if(c != EOF)
{
strRet[pos] = c;
pos=pos+1;
}
else
{
finito=YES;
}
}while(c != EOF && c != '\n');
if (pos!=0)
{
strRet[pos] = '\0';
}
NSString *stringa=[NSString stringWithCString:strRet encoding:NSASCIIStringEncoding];
if (pos==0)
{
stringa=@"";
}
long long sizerecord;
if (pos!=0)
{
sizerecord= (long long) [[NSString stringWithFormat:@"%ld",sizeof(char)*(pos)] longLongValue];
}
else
{
sizerecord=0;
}
pos = pospass + pos;
NSDictionary *risultatoc = @{st_risultatofunzione: stringa,
st_criterio: [NSString stringWithFormat:@"%d",pos],
st_finito: [NSNumber numberWithBool:finito],
st_size: [NSNumber numberWithLongLong: sizerecord]
};
//Svuoto il buffer
free(strRet);
// free(tmpStr);
strRet=NULL;
return risultatoc;
}
然而,当我在文件中有一个特殊字符(例如€符号或重音字母或某些北欧国家)时,记录无法正确读取,我发现自己带有随机字符的NSString而不是正确的。 你知道你帮帮我吗?谢谢!
答案 0 :(得分:1)
以下行告诉iOS您有ASCII数据:
NSString *stringa= [NSString stringWithCString:strRet encoding:NSASCIIStringEncoding];
但是,€符号或重音字母不是ASCII的一部分。所以你显然有不同的。
找出它的编码(例如UTF-8,Windows ANSI,ISO-8859-1)并相应地更新该行,例如:
NSString *stringa= [NSString stringWithCString:strRet encoding: NSWindowsCP1251StringEncoding];
<强>更新强>
弄清楚正在使用的编码可能很棘手。
根据我的经验,VB6和SQL Server是一对很好的,因为它们通常不会弄乱编码。弱部分是文本文件,它取决于编码,但不包含有关使用什么编码的任何显式信息。 VB6可能使用Windows默认设置,这取决于您的语言设置。不幸的是,我不知道在哪里可以看到Windows中的默认编码。
在西方国家/地区,编码通常设置为Windows ANSI aka Code Page 1251(常量NSWindowsCP1251StringEncoding
来自的地方)。
您可以或多或少地验证它。如果打开包含欧元符号(€)的文本文件,则必须使用值80(十六进制),如果它在CP 1251中编码。在Latin-1(又名ISO-8859-1)中,您不能表示欧元符号。在Latin-9(又名ISO-8859-15)中,它将使用A4(十六进制)。在UTF-8中,需要三个字节:E2 82 AC。
请亲自检查一下。如果您不确定,请添加文本文件相关部分的十六进制转储。