【问题标题】:How to access the characters in getline() in C如何在 C 中访问 getline() 中的字符
【发布时间】:2016-10-16 01:48:30
【问题描述】:

我正在尝试从 getline() 访问文本,以便扫描它以查找特殊字符。该程序从一个文件中读取并创建另一个文件,但是我必须从第一个文件中删除 cmets 并将其打印到没有 cmets 的第二个文件中。在这种情况下,我需要能够读取所有 '%' 并删除右侧的所有内容。这是我家庭作业的一部分,我不是在找人来完成它并作弊。我只需要找到一种方法将行存储在 char 数组中,这样我就可以遍历并找到一个 '%'(如果存在)。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){


    FILE *fp, *fp2;

    char *line = NULL;
    size_t len = 0;
    ssize_t read = 0;
    //int i = 0;

    //line = test;

    fp = fopen("taxDemo.m", "r");
    fp2 = fopen("taxDemoNoComments.m", "w");

    if(fp == NULL)
        exit(EXIT_FAILURE);


    while((read = getline(&line, &len, fp)) != -1){
        /* for (i = 0; i < len; i++){
            test[i] = line;
            line++;
        }
        */

        //printf("%s", test);

        printf("%s", line);

        fprintf(fp2, "%s", line);
    }


    free(line);
    fclose(fp);
    fclose(fp2);

    return 0;
}

【问题讨论】:

  • 如果(fp == NULL)退出(EXIT_FAILURE)之后;你应该添加一个 if(fp2 == NULL) exit(EXIT_FAILURE);
  • line 指向该行的第一个字符...您还需要知道什么?

标签: c getline


【解决方案1】:

这是基于您的代码的解决方案。我添加了示例文件的创建和行的分配。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {

    FILE *fp, *fp2;

    char *line = NULL;
    size_t len = 1024;
    size_t read = 0;

    line = (char*) malloc(len * sizeof(char));
    if (line == NULL) {
        perror("Unable to allocate line...");
        exit(1);
    }
//Create sample file
    fp = fopen("taxDemo.m", "w+");

    for (int i = 0; i < 10; i++) {
        fprintf(fp, "Non commented part of the line %i %% Commented \n", i);
    }
    fclose(fp);
    fp = fopen("taxDemo.m", "r");
    fp2 = fopen("taxDemoNoComments.m", "w");

    if (fp == NULL)
        exit(EXIT_FAILURE);

    while ((read = getline(&line, &len, fp)) != -1) {
        for (int i = 0; i < len; i++) {
            if (line[i] == '%')
                line[i] = '\0';
        }

        printf("%s\n", line);

        fprintf(fp2, "%s\n", line);
    }
   free(line);
    fclose(fp);
    fclose(fp2);

    return 0;
}

【讨论】:

  • 调用getline()之前真的不需要分配;给定一个空指针和零长度,它分配得相当愉快,并且通常在第一次调用时分配一个相当大的长度(例如 256 字节)。当第一次调用 getline() 返回 -1 以指示 EOF 时,它通常甚至会执行该分配。像你一样释放它很重要。请注意,即使只读取了 10 个字符,您的内部 for 循环也会迭代超过 1024 个字符。这是值得怀疑的。当您写入空字节时,您也可以/应该打破内部循环;没有必要继续搜索。
  • 另外,还有一个名为strchr() 的函数可能有用。如果一行没有附加注释,那么你打印一个空行——只是说。
  • @JonathanLeffler:非常好的观点,感谢一百万修复我的遗漏!
【解决方案2】:
  1. 遍历查找% 的行的内容,并在找到时执行您需要执行的操作。

    char* cp = line;
    for ( ; *cp != '\0'; ++cp )
    {
       if ( *cp == '%' )
       {
          // Do what you need to do.
          // If you want to ignore everything after the % but leave the %, use
          *(cp + 1) = '\0';
    
          // If you want to ignore % and everything after it, use
          *cp = '\0';
       }
    }
    
    // Print the line
    
  2. 我建议使用fgets 而不是getline,因为getline 不是标准C 库函数。

    char line[MAX_LINE_LENGTH];   // #define MAX_LINE_LENGTH to suit your needs
    while( fgets(line, sizeof(line), fp) != NULL ){
    

【讨论】:

  • fgets 不会返回长于 MAX_LINE_LENGTH 的行(这可能比最长的行短)。我编写了自己的 getline 函数来解决这个问题,如果他们被允许使用这样的函数,可能是有原因的,老师的想法是让他们逐步学习编码,而不是让他们学习一下子搞定一切。
  • 我用 fgets 编写了另一个程序,它对我来说效果更好,但我的教授希望我们使用 getline()。也很抱歉格式不好,这是我第一次提出问题。
  • @CiscoAbril,无论您是使用getline 还是fgets 从文件中读取数据,我的迭代行内容的建议/代码都应该有效。
  • @RSahu 非常感谢您!我最终会在 for 循环的第一部分使用什么? for ( xxxx ; *cp != '\0'; ++cp )
  • 我不同意开头的建议,当问题明确询问功能时,我不同意。如果问题是使用fgets(),那么不用提getline() 等就可以了,但建议他们停止使用他们正在使用的东西似乎——傲慢,还是傲慢?
猜你喜欢
  • 2021-08-01
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2010-10-11
相关资源
最近更新 更多