我正在从文件中读取一行,但我不知道它的长度。我知道有办法用指针做这个,但我特别要求一个计划字符串。例如,如果我像这样初始化字符串:
char string[300]; //(or bigger)
像这样的大字符串值会出现问题吗?
答案 0 :(得分:3)
任何硬编码的数字可能太小而无法读取文件的内容。最好在运行时计算大小,为内容分配内存,然后读取内容。
答案 1 :(得分:2)
char string [300]; //(或更大)
我不确定您关注哪两个问题,因此我将尝试解决以下问题:
如果文件中的字符串大于300字节并且您尝试"坚持"该缓冲区中的那个字符串,没有计算数组的最大长度 - 由于覆盖了数组,你将得到未定义的行为。
如果你只是询问300字节是否过多分配 - 那么不,除非你在一些非常有限的设备上,否则它不是什么大问题。例如在Visual Studio中,如果我没有错,则默认堆栈大小(存储该数组的位置)为1 MB。这样做的好处是可以理解的,例如你不需要关心自己等等。
PS。因此,如果您确定您指定的缓冲区大小足够 - 这可以是一个很好的方法,因为您可以从内存管理相关问题中解脱出来 - 您可以从指针和动态内存中获得。
答案 2 :(得分:0)
像这样的大字符串值会出现问题吗?
绝对
如果您的应用程序在处理之前必须从文件读取整行,那么您有两个选择。
1)分配大到足以容纳最大允许长度的缓冲区。例如,SMTP协议不允许超过998个字符的行。在这种情况下,您可以分配长度为1001的静态缓冲区(998 + \r
+ \n
+ \0
)。从文件(或客户端,在示例上下文中)读取一行,其长度超过最大长度(即,您已读取1000个字符,最后一个不是\n
),可以将其视为致命(协议)错误并报告。
2)如果对输入行的长度没有限制,那么唯一可以确保程序健壮性的是在读取输入时动态分配缓冲区。这可能涉及在链接列表中存储多个malloc
-ed缓冲区,或者在检测到缓冲区耗尽时调用realloc
(这是getline
函数的工作方式,尽管C标准中未指定,仅限于POSIX.1-2008)。
在任何一种情况下,都不要使用gets
来读取该行。请改为呼叫fgets
。
答案 3 :(得分:0)
这完全取决于你如何阅读这条线。例如:
char string[300];
FILE* fp = fopen(filename, "r");
//Error checking omitted
fgets(string, 300, fp);
取自tutorialspoint.com
C库函数char * fgets(char * str,int n,FILE * stream)从指定的流中读取一行并将其存储到str指向的字符串中。当读取(n-1)个字符,读取换行符或达到文件结尾时(以先到者为准),它会停止。
这意味着这将最多从文件中读取299个字符。这将导致仅出现逻辑错误(因为您可能无法获得所需的所有数据),这不会导致任何未定义的行为。
但是,如果你这样做:
char string[300];
int i = 0;
FILE* fp = fopen(filename, "r");
do{
string[i] = fgetc(fp);
i++;
while(string[i] != '\n');
这将导致Segmantation Fault,因为它会尝试在大于300个字符的行上写入未分配的内存。