C:strcat()终止程序而没有错误

我正在Windows机器上编写C代码。这是我第一个认真的C程序,所以我可能不了解很多词汇。

我正在尝试编写一个程序,该程序从文本文件中读取字符并将它们放入字符串中。

# include <stdio.h>
# include <string.h>
# define MAXCHAR 10

char* load_html(char* filename) {
  FILE *file;

  file = fopen(filename,"r");
  if (file == NULL) {
    printf("File not found %s",filename);
    return NULL;
  }

  char str[MAXCHAR];
  char* html= "";

  while (fgets(str,MAXCHAR,file) != NULL) {
    printf(str);
    //strcat(html,str);
  }

  return html;
}

int main() {
  char* filename = "load_html.c";
  load_html(filename);

  return 0;
}

当我编译(gcc -o load_html.exe .\load_html.c)并运行这段代码时,它运行得很好,并将该程序的源代码输出到控制台。但是,如果我取消注释strcat

  while (fgets(str,file) != NULL) {
    printf(str);
    strcat(html,str);
  }

程序将读取文件的第一行,暂停1至2秒钟,然后无错误退出。

这到底是怎么回事?我觉得我缺少一些非常重要的东西。

iCMS 回答:C:strcat()终止程序而没有错误

html是指向字符串文字的指针,它们不能更改(通常存储在内存的只读部分中),这是strcat试图执行的操作,调用undefined behavior

即使不是这种情况,html显然也太小了,无法容纳其他任何东西,因为它只能容纳1个字符。

应该是:

char html[SIZE] = "";

SIZE必须足够大以容纳所有串联的字符串。

在这种情况下,您在返回html时遇到问题,如果它不是指针,它将是一个局部变量,该函数的生命周期将终止。您可以通过以下方式解决此问题:


  1. 保留html作为指针并为其分配内存:
#include <stdlib.h>
//...
char *html = malloc(SIZE);

完成后,您需要free(html)


  1. 或将指向char的指针作为函数的参数传递:
void load_html(char* filename,char* html){ //void return type

    //remove declaration of html
    //do not return anything
}

在主要方面:

int main(){

    char* filename = "load_html.c";
    char html[size]; //buffer to store the concatenated string
    load_html(filename,html); //the string will be stored in the buffer you pass as an argument

}

我宁愿选择第二种选择,因为您不需要分配内存,这是一种更昂贵的方法,会迫使您手动管理内存。


printf(str)也是格式错误的,此功能需要格式说明符来打印格式化的输出:

printf("%s" str);

或仅使用puts(str)

,

在此声明中

char* html= "";

您声明了指向字符串文字""的指针。

然后在此声明中

strcat(html,str);

您正在尝试更改指向的字符串文字。

但是,您不能更改字符串文字。根据C标准(6.4.5字符串文字)

7不确定这些数组是否有区别,只要它们的 元素具有适当的值。 如果程序尝试执行以下操作 修改这样的数组,行为是不确定的。

因此,如果要累积从文件中读取的字符串,则需要定义足够大的字符数组。

例如

char html[MAXCHAR * MAXCHAR];
html[0] = '\0';

但是在这种情况下,还会出现另一个问题,因为您可能无法从函数中返回一个本地数组,而该函数在退出该函数后将不处于活动状态。

因此,一种更灵活,正确的方法是在while循环中为从文件中读取的每个新字符串动态地重新分配字符数组。

类似

char *htmp = calloc( 1,sizeof( char ) );
size_t n = 1;

while (fgets(str,MAXCHAR,file) != NULL) {
    printf(str);

    n += strlen( str );

    char *tmp = realloc( html,n );

    if ( tmp == NULL ) break;

    html = tmp;

    strcat(html,str);
}

// ...

return html;

在主要情况下,当不再需要该数组时,应该释放分配的内存。

free( html );
,

html是指向1字节内存的指针。该内存是只读的,因为它是静态分配的字符串。 strcat会覆盖它,未定义的行为也会被覆盖,原因有两个:写内存超出范围,写到只读内存。

您看到的任何怪异行为(例如:程序提前退出)都可能是这种情况造成的。

本文链接:https://www.f2er.com/1637902.html

大家都在问