【问题标题】:The puts() only prints the last element of the text fileputs() 只打印文本文件的最后一个元素
【发布时间】:2020-05-27 04:04:33
【问题描述】:

我有一个文本文件,里面有我想以字符串形式存储在 S 中的文本

FILE *fp;

char str[200];

char **S = malloc( 200000*sizeof( char ) );

int i=0, j;

fp = fopen("S.txt" , "r");

while( fgets (str, 200, fp)!=NULL ) 
{
    S[i] = str;
    i++;
}

for(j=0;j<i;j++)
    puts(S[j]);

fclose(fp);

但问题是程序只打印列表的最后一个字符串。我认为可能是我分配了错误的内存(malloc( 200000*sizeof( char ) ),因为该文件包含多达 1000 个最多 200 个字符的字符串)

【问题讨论】:

  • S[i] = str; 只将str 的地址复制到S[i],而不是字符串的内容。

标签: c


【解决方案1】:
FILE *fp;

char str[200];

/* <<<ATTENTION, READ HERE>>>
 * Here, the allocation size is incorrect, one of two:
 * You should use malloc( 200000 * sizeof (char *)); as you are
 *     allocating the pointers in the array, not the space for 
 *     the strings 
 * You express (always safe) malloc( 200000 * sizeof *S ); This is
 *     a fake expression (not evaluated but to get the sizeof only)
 */
char **S = malloc( 200000 * sizeof *S );

int i=0, j;

fp = fopen("S.txt" , "r");

while( fgets (str, 200, fp)!=NULL ) 
{

    /* <<<ATTENTION, READ HERE>>>
     * the strdup(str); allocates memory (calling malloc itself)
     * and copies the contents of the string in the allocated memory.
    S[i] = strdup(str);
    i++;
}

for(j=0;j<i;j++)
    puts(S[j]);

fclose(fp);

通过这两项修改,您的程序将安全运行(考虑到您不能允许超过 200000 行且不超过 200 个字符的文件)

您的问题,而不是strdup()ing 字符串是您最终使所有字符串都指向缓冲区,因此在读取最后一行内容所读取的所有行之后缓冲区的内容。由于所有指针都指向同一个位置,因此您获得了最后一行的尽可能多的副本(在双倍空格处,因为fgets() 不会将\n 从字符串中取出,但puts() 确实在之后添加了\n打印传递的字符串。

注意

请阅读how to create a minimum, complete and verifiable example,因为如果您决定只发布一段 sn-p 代码,您可以轻松消除错误。此外,我们更难以验证和检查您的错误,或者从什么是错误中检测出什么是错字。

注意2

如果您想返回程序分配的所有内存,您可以执行以下操作:

for(j = 0; j < i; j++)
    free(S[j]); /* each malloc made inside strdup() */
free(S); /* the malloc you did at the beginning */

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多