【问题标题】:write into a file with fprintf使用 fprintf 写入文件
【发布时间】:2019-03-25 03:05:57
【问题描述】:

我尝试使用此功能写入文件。 当我用这一行调用函数时,文件保持为空:

if(argc-optind==0){
  char* line=readcli();
  printf("testline:%s\n",line); //WORKS
  line=replacet(line,t,countt(line));
  if(oFlag==1){
    writeinfile(line,oFileName);
  }else{
    printf("Expanded:%s\n",line);
  }
}

但如果我这样称呼它,它会起作用:

char text[]={"test"};
char * textptr=text;
writeinfile(textptr,fp);

void writeinfile(char* line,char* file){
  FILE *f = fopen(file, "a");
  if (f == NULL){
    printf("Error opening file!\n");
    exit(1);
  }
  fprintf(f, "Some text: %s\n",line);
  fclose(f);
}

用空格替换制表符

char* replacet (char *text, int tabsize, int tabanz){
    int newsize=strlen(text)+tabsize*tabanz-tabanz;
    char newtext[newsize];//Wenn \t nu ein zeichen ist
    char* ptrnew=newtext;
    char* ptr=text;
    for(int i=0;i<strlen(text);i++,ptr++){
        if(text[i]=='\t'){
            for(int j=0;j<tabsize;j++){
                *ptrnew=' ';
                ptrnew++;
            }
        }else{
            *ptrnew=text[i];
            ptrnew++;
        }
    }
    char* newtextptr=newtext;
    return newtextptr;
}

读取在命令行界面输入的一行

char* readcli(){
    char *buffer;
    size_t bufsize = 64;
    size_t chars;
    buffer = (char *)malloc(bufsize * sizeof(char));
    if( buffer == NULL){
        perror("Error malloc");
    }    
    printf("Type something with Tabulators: ");
    chars = getline(&buffer,&bufsize,stdin);
    printf("%zu characters were read.\n",chars);
    return buffer;
}

请帮助我,我不知道如何解决它。 谢谢

【问题讨论】:

  • 敢向我们展示line=replacet(line,t,countt(line)); 的作用吗?由于这条线似乎是两个 sn-ps 之间的明显区别。
  • 另外,oFlag 的值是多少? printf("Expanded:%s\n",line); 被执行了吗?
  • 什么是oflag? readcli() 是什么? replacet() 是什么?
  • @alk 我编辑了我的问题添加了替换,它只是用空格替换制表符,countt 只计算给定行中有多少个制表符

标签: c string dynamic-memory-allocation c-strings local-variables


【解决方案1】:

两期:

  • 这里

    char* replacet (char *text, int tabsize, int tabanz){
      int newsize=strlen(text)+tabsize*tabanz-tabanz;
      char newtext[newsize];//Wenn \t nu ein zeichen ist
      ...
      char* newtextptr=newtext;
      return newtextptr;  /* <-- HERE */
    

    返回一个局部变量的地址 (newtext)。内存只有在函数内部才有效。

    函数返回的那一刻,内存被自动释放。在函数返回后访问它会调用臭名昭著的未定义行为。从那一刻起,任何事情都可能发生。不要这样做。

  • 函数replacet()错过了0-终止新的C-“字符串”。

修复所有这些替换

  char newtext[newsize];

通过

  char * newtext = malloc(newsize + 1); /* +1 for 0-terminator each
                                           c-"string" needs */
  if (NULL == newtext) /* Error checking is debugging for free. */
  {
    return NULL;
  }

在离开之前添加0-终止符:

  newtext[i] = '\0'; /* or just the equivalent: ... = 0; */
  char* newtextptr = newtext;
  return newtextptr;
}

从

更改调用代码
  line=replacet(line,t,countt(line));

到

  {
    char * pctmp = replacet(line, t, countt(line));
    if (NULL == pctmp)
    {
      /* exit or do what error handling made sense */
      exit(EXIT_FAILURE); /* include stlib.h for the EXIT_* macros */
    }
    else
    {
      free(line);
      line = pctmp;
    }
  }

【讨论】:

  • 谢谢 :D char * pctmp =replacet(line,t,countt(line)); 所以我必须使用这个新指针,因为该函数释放了我的行变量的存储空间?
  • "该函数释放了我的行变量的存储空间" 不,因为里面没有空闲。 (这样做是另一种编码方式)你需要这样做。在我上次的 sn-p 中,代码会这样做,但前提是函数成功分配并返回“新”内存。见if (NULL == pctmp) { ... } else {... }
  • “必须使用这个新指针”,因为它保存着你的新数据。
  • 您无法通过扩展选项卡来修补现有字符串 (line)。这你显然已经意识到了。
  • 在我之前的一个 cmets 中,这个“因为它持有”应该是“因为它指向”!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多