是否会为char字符串的长度分配一个大值?

时间:2016-02-01 21:16:38

标签: c string

我正在从文件中读取一行,但我不知道它的长度。我知道有办法用指针做这个,但我特别要求一个计划字符串。例如,如果我像这样初始化字符串:

char string[300]; //(or bigger)

像这样的大字符串值会出现问题吗?

4 个答案:

答案 0 :(得分:3)

任何硬编码的数字可能太小而无法读取文件的内容。最好在运行时计算大小,为内容分配内存,然后读取内容。

请参阅Read file contents with unknown size

答案 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个字符的行上写入未分配的内存。